CyberJunkie
CyberJunkie

Reputation: 22674

PHP recreate array if it contains certain values

I have $fruits_arr:

Array
(
    [0] => Array
        (
            [id] => 213
            [fruit] => banana
        )

    [1] => Array
        (
            [id] => 438
            [fruit] => apple
        )

    [2] => Array
        (
            [id] => 154
            [fruit] => peach
        )
)

And $ids_arr:

Array ( 
  [0] => 213
  [1] => 154 
)

I want to recreate $fruits_arr to have only array items where id is equal to a value from $ids_arr. I also want to maintain the index/array order of $fruits_arr.

I'm using the following:

$selected_fruits = array();

foreach( $fruits_arr as $fruit ) :
    if ( in_array( $fruit['id'], $ids_arr ) ) :
        $selected_fruits[] = $fruit;
    endif;
endforeach;

print_r( $selected_fruits );

It seems to work but I am wondering if there is a shorter, better way to accomplish this in the latest PHP version.

Upvotes: 1

Views: 89

Answers (4)

The fourth bird
The fourth bird

Reputation: 163287

This is not a shorter or newer way, but perhaps instead of performing in_array for every iteration, you could use array_flip and then use isset to check for the key:

$ids_arr = array_flip($ids_arr);
$selected_fruits = [];

foreach ($fruits_arr as $k =>  $fruit) {
    if (isset($ids_arr[$fruit["id"]])) {
        $selected_fruits[$k] = $fruit;
    }
}

Php demo

Upvotes: 2

Progrock
Progrock

Reputation: 7485

Keeping it simple, a loop where you remove items that are not in your keep array.

<?php

$fruits =
[
    'foo' => [
        'id' => 1,
        'fruit' => 'banana'
    ],
    'bar' => [
        'id' => 2,
        'fruit' => 'orange'
    ],
    'baz' => [
        'id' => 3,
        'fruit' => 'pear'
    ],    
];

$keep_ids = [1,3];

foreach($fruits as $k=>$v)
    if(!in_array($v['id'], $keep_ids))
        unset($fruits[$k]);

var_export($fruits);

Output:

array (
  'foo' => 
  array (
    'id' => 1,
    'fruit' => 'banana',
  ),
  'baz' => 
  array (
    'id' => 3,
    'fruit' => 'pear',
  ),
)

Upvotes: 0

Andreas
Andreas

Reputation: 23958

If the array is associative (use array_column for that) then you can use array_intersect_key to do the job.

$fruits_arr = array_column($fruits_arr, Null, "id");

$result = array_intersect_key($fruits_arr, array_flip($ids_arr));

var_dump($result);

https://3v4l.org/jQo6E

Upvotes: 0

Dharman
Dharman

Reputation: 33238

You could use array_filter to make it more concise, but it will not be much and could make your code less readable. If possible chose readability over length of code.

$selected_fruits = array_filter($fruits_arr, function ($el) use ($ids_arr) {
    return in_array($el['id'], $ids_arr, true);
});

or you can wait for PHP 7.4 (due to come out at the end of the year) and use arrow functions.

$selected_fruits = array_filter($fruits_arr, fn ($el) => in_array($el['id'], $ids_arr, true));

Demo: https://3v4l.org/4UC41

Upvotes: 1

Related Questions