3

I think this should be something simple, but I can't find a way to do it.

I have two arrays, one with colors and ids

$color_ids = [
 'green' => [1,2,3],
 'blue' => [4,5],
 'red' => [6],
 'pink' => [7,8,9],
 'yellow' => [10]
];

and others with selection.

$select = ['green', 'red', 'yellow'];

Then I need the ids where intersects keys between $color_ids and $select. This should be the result (a simple linear array):

$results = [1,2,3,6,10];

I've tried this:

$result = array_values(array_intersect_key( $color_ids, array_flip($select ) ) );;

But I get multidimensional array:

array(3) { 
   [0]=> array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } 
   [1]=> array(1) { [0]=> int(6) } 
   [2]=> array(1) { [0]=> int(10) }
}

I get the same result with this:

$result = [];
foreach ($select as $key) {            
  if (isset($color_ids[$key]))
    $result[] = $color_ids[$key];              
}   

How can I get a simple linear array with ids?

Łukasz D. Tulikowski
  • 1,440
  • 1
  • 17
  • 36
kurtko
  • 1,978
  • 4
  • 30
  • 47

4 Answers4

4

1) Iterate over the key array

2) Merge all the arrays into one using array_merge

 $select = ['green', 'red', 'yellow'];
 $finalArray=[];
   foreach($select as $value){
     $finalArray= array_merge($finalArray,$color_ids[$value]);
   }
 echo "<pre>";
 print_r($finalArray);

Output:

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 6
    [4] => 10
)
Danyal Sandeelo
  • 12,196
  • 10
  • 47
  • 78
1

You can use array_merge with the ... operator which is a common flattening technique demonstrated here.

array_merge(...$result);

Array Merge documentation.

Splat Operator documentation.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
jrenk
  • 1,387
  • 3
  • 24
  • 46
0

with foreach

$result = [];
foreach($color_ids as $color => $ids){
  $result = array_merge($result, in_array($color, $select) ? $ids : []);
}
jspit
  • 7,276
  • 1
  • 9
  • 17
0

If you are looking for a fully "functional style" solution, here's one.

  • Set up your filtering array ($select) so that it has keys like the master array's keys. In other words, flip the values into keys.
  • Then swiftly filter the master array using array_intersect_key().
  • Then to flatten the remaining data, prepend the splat/spread operator and call array_merge().

Until you are on a php version that allows associative arrays to be spread, then you'll need to call array_values() to reindex the first level keys so that the spread operator doesn't choke.

Code: (Demo)

var_export(
    array_merge(
        ...array_values(
            array_intersect_key(
                $color_ids,
                array_flip($select)
            )
        )
    )
);

Or if you prefer jumble the syntax into a single line:

var_export(array_merge(...array_values(array_intersect_key($color_ids, array_flip($select)))));

Although a foreach() may perform a few nanoseconds faster than functional programming, you are never going to notice on such small data sets. One benefit of this coding style is that you don't have to name any temporary variables to push qualifying data into. In other words you can feed this directly into a return statement inside of a function which I find to be very tidy.


Alternatively, if you don't mind generating a result variable, then iterated array_push() calls while spreading the matching nominated color_id value is pretty simple. This technique is different in that if $select contains a color that is not a key in $color_id, then php will bark at you!

Code: (Demo)

$result = [];
foreach ($select as $color) {
    array_push($result, ...$color_ids[$color]);
}    
var_export($result);

Both techniques offer the same result.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136