简体   繁体   中英

php: simplest way to turn an indexed two-dimensional array into an associatively indexed-by-a-contained-value two-dimensional array?

I continually find myself running queries on databases and getting multidimensional arrays representing rows back. Unfortunately, the first level index is numeric, which isn't very informative. I frequently have tables with identity strings in the table, and want to turn the resulting multidimensional array into something that's associatively indexed by that identity column.

An inelegant self-created custom function to do what I want:

function identity_associate($data, $identity_column='identity'){
    $res = array();
    foreach($data as $single_row){
        $loop_identity = $single_row[$identity_column];
        $res[$loop_identity] = $single_row;
    }
    return $res;
}

Obviously I could use a foreach loop each time I wanted to do this, or use that function to do it for me when I pass the data to it each time, but if there's a built-in way to do this trivially with native php functions, I'd prefer to use that to make the correction instead. I tried to find something appropriate in the php docs for sorting and arrays, but couldn't find anything exact, and google wasn't much help either. Anyone know of something php native or otherwise simpler?

ie I want to convert the data that I get when I query the database...

array(
  array(
    'user_id'=>45,
    'identity'=>'bob',
    'name'=>'Bob'
  ),
  array(
    'user_id'=>51, 
    'identity'=>'tchalvak', 
    'name'=>'TchalVak'
  )
);

into something more usable

array(
  'bob'=>array(
    'user_id'=>45, 
    'identity'=>'bob', 
    'name'=>'Bob'
  ), 
  'tchalvak'=>array(
    'user_id'=>51, 
    'identity'=>'tchalvak', 
    'name'=>'TchalVak'
  )
);

as optimized-ly as possible, since it's something that I would use everywhere all the time.

Edit:

I want to point out that I'm getting the data in that format from the database by calling a built-in function in PDO and it's returning the equivalent of the first array:

$statement->execute();
return $statement->fetchAll(PDO::FETCH_ASSOC);

Eg calling the sql below:

$data = query('select name, user_id, identity from users order by identity');

...would get the first array at the top in the question.

I was thinking about shifting the first element off by applying array mapping the array_unshift() function then pairing the array returned by array_map() and the original array with array_combine() . Here's a sample, keep in mind it will only work when the identity element is the first element of the sub-arrays:

<?php
$arrs = array(
            array(
                'identity'=>'bob',
                'user_id'=>45,
                'name'=>'Bob'
            ),
            array(
                'identity'=>'tchalvak',
                'user_id'=>51, 
                'name'=>'TchalVak'
            )
        );

$identites = array_map( 'array_shift', $arrs );
$formatted = array_combine( $identites, $arrs );
print_r( $formatted );
?>

If necessary you could craft a helper function to pass to array map if the identity is not the first element.

<?php
$arrs = array(
            array(
                'identity'=>'bob',
                'user_id'=>45,
                'name'=>'Bob'
            ),
            array(
                'identity'=>'tchalvak',
                'user_id'=>51, 
                'name'=>'TchalVak'
            )
        );

$identites = array_map( 'array_grab', $arrs );
$formatted = array_combine( $identites, $arrs );
print_r( $formatted );

function array_grab( $array ) { return( $array['identity'] ); }
?>

I believe your array is to custom too have anything built in to PHP. You may be able to use array_map and save on a foreach, but that's not really saving much (and eliminating your $identify_column argument).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM