16

Just for curiosity (I know it can be a single line foreach statement), is there some PHP array function (or a combination of many) that given an array like:

Array (
    [0] => stdClass Object (
        [id] => 12
        [name] => Lorem
        [email] => [email protected]
    )
    [1] => stdClass Object (
        [id] => 34
        [name] => Ipsum
        [email] => [email protected]
    )
)

And, given 'id' and 'name', produces something like:

Array (
    [12] => Lorem
    [34] => Ipsum
)

I use this pattern a lot, and I noticed that array_map is quite useless in this scenario cause you can't specify keys for returned array.

8
  • 3
    Probably not, but you can write your own function :) Commented Aug 21, 2012 at 8:29
  • 2
    array_map can take a custom function, and you can use that to specify the array keys. Commented Aug 21, 2012 at 8:36
  • 1
    @Ariel How? I can't find a way to specify keys for array_map returned array. Commented Aug 21, 2012 at 8:48
  • 2
    This does the trick: return array_reduce($options, function(&$r, $x){ $r[$x->property] = $x->property2; return $r;}); Commented Nov 20, 2014 at 19:53
  • 1
    You can use array_column($arr, 'name', 'id'); you can also see in my answer for more details Commented Aug 26, 2022 at 4:53

5 Answers 5

29

Just use array_reduce:

$obj1 = new stdClass;
$obj1 -> id = 12;
$obj1 -> name = 'Lorem';
$obj1 -> email = '[email protected]';

$obj2 = new stdClass;
$obj2 -> id = 34;
$obj2 -> name = 'Ipsum';
$obj2 -> email = '[email protected]';

$reduced = array_reduce(
    // input array
    array($obj1, $obj2),
    // fold function
    function(&$result, $item){ 
        // at each step, push name into $item->id position
        $result[$item->id] = $item->name;
        return $result;
    },
    // initial fold container [optional]
    array()
);

It's a one-liner out of comments ^^

Sign up to request clarification or add additional context in comments.

Comments

5

I found I can do:

array_combine(array_map(function($o) { return $o->id; }, $objs), array_map(function($o) { return $o->name; }, $objs));

But it's ugly and requires two whole cycles on the same array.

1 Comment

You should probably do this manually (i.e. a foreach loop) - it'll likely be faster than this.
5

The easiest way is to use an array_column()

$result_arr = array_column($arr, 'name', 'id');
print_r($result_arr );

Out Put

Array (
    [12] => Lorem
    [34] => Ipsum
)

1 Comment

Best/shortest solution!
0

The easiest way is to use a LINQ port like YaLinqo library*. It allows performing SQL-like queries on arrays and objects. Its toDictionary function accepts two callbacks: one returning key of the result array, and one returning value. For example:

$userNamesByIds = from($users)->toDictionary(
    function ($u) { return $u->id; },
    function ($u) { return $u->name; }
);

Or you can use a shorter syntax using strings, which is equivalent to the above version:

$userNamesByIds = from($users)->toDictionary('$v->id', '$v->name');

If the second argument is omitted, objects themselves will be used as values in the result array.

* developed by me

Comments

-1

Because your array is array of object then you can call (its like a variable of class) try to call with this:

 foreach ($arrays as $object) {
    Echo $object->id;
    Echo "<br>";
    Echo $object->name;
    Echo "<br>";
    Echo $object->email;
    Echo "<br>";
 } 

Then you can do

 // your array of object example $arrays;
 $result = array();
 foreach ($arrays as $array) {
       $result[$array->id] = $array->name;
 }

   echo "<pre>";
   print_r($result);
   echo "</pre>";

Sorry I'm answering on handphone. Can't edit the code

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.