4

Sorry for the vague title, I had trouble summarizing this question in one sentence (I'm open to suggestions or edits).

I have a 2 dimensional associative array with an array of 2 numbers for each key.

Like this:

Array
   (
   [one] => Array
      (
      [0] => 1
      [1] => 2
   )
   [two] => Array
      (
      [0] => 1
      [1] => 2
   )
   [three] => Array
      (
      [0] => 1
      [1] => 2
   )
)

I'm wondering if there is a way to use array_map() or array_filter() to return an array that has each key and the first number in each of the value arrays, like this:

Array
   (
   [one] => 1
   [two] => 1
   [three] => 1
)

I do not wish to create a new array by using a loop or anything like that, I'd like to do the conversion on the fly as an argument to a function, if you know what I mean.

I could write my own function to achieve this but I'm interested in knowing if it can be done with array_map() or array_filter().

I tried using various combinations of array_merge(), array_keys() and array_values() with no success.

I thank you in advance for any help you may provide.

vulpinus
  • 79
  • 1
  • 7

5 Answers5

3

I think it would be better to use loop instead in this condition. However this one should work with your case.

<?php

$arr = array(
   "one" => array(1, 2),
   "two" => array(1, 2),
   "three" => array(1, 2)
);
$res = array();

array_walk($arr, function ($v, $k) use (&$res) {
    $res[$k] = $v[0];
});

print_r($res);
Ammar Faizi
  • 1,393
  • 2
  • 11
  • 26
2

The first solution is:

$keys = array_keys($ar);             // get all keys
$vals = array_column($ar,0);         // get all values with 0 index
$res = array_combine($keys,$vals);   // combine them

By the way, you don't need to use some extra function, simple foreach loop would be enough:

$res = [];
foreach($arr as $key=>$val){
    $res[$key] = $val[0];
}

You can see the difference between performances of array_walk and foreach function here.

Aksen P
  • 4,564
  • 3
  • 14
  • 27
  • Thanks, was not aware of array_column(), will definitely be using it in future. Although this is not quite what I was looking for.. I am trying to see if it is possible to do it in just 1 function call instead of 3. – vulpinus Nov 21 '19 at 16:38
  • @vulpinus, yes, it's possible. That's why I've wrote *the first solution*. – Aksen P Nov 21 '19 at 16:43
2

with array_map you can do somthing like that :

$array_2= array_map(function ($sub_array) {
 $new_value  =   $sub_array[0];
 return $new_value;
},$array_1);
R. Martin
  • 411
  • 2
  • 11
  • 1
    Explain what are `$array_2`, `$array_1` and `$sub_array`. – Aksen P Nov 21 '19 at 16:46
  • 1
    `$array_1` is the input data, `$array_2` is the output data that we want. and `$sub_array` in fact they are sub arrays inside first array. take a look at my answer i use the same approach but with a callback function and more details. I hope it helps! – XMehdi01 Apr 18 '21 at 19:52
2

You can use array_reduce to iteratively reduce the array.

return array_reduce(array_keys($attribs), function($carry, $key) use ($attribs){
        $carry[$key]= $attribs[$key][0];
        return $carry;
    });

Hope this help,

2

Yes, it can be done using only one function array_map with a callback:

  1. map will iterate over arrays inside $arr
  2. callback take only first element of array as you want.
<?php
$arr = array(
   "one" => [1, 2],
   "two" => [1, 2],
   "three" => [1, 2]
);
$res = array_map(fn($sub_arr)=>$sub_arr[0],$arr);

echo "<pre>";
print_r($res);
/*
Array
(
    [one] => 1
    [two] => 1
    [three] => 1
)
*/
XMehdi01
  • 5,538
  • 2
  • 10
  • 34