user137621
user137621

Reputation:

Matching an array value by key in PHP

I have an array of items:

array(
  [0] => array(
    'item_no' => 1
    'item_name' => 'foo
  )
  [1] => array(
    'item_no' => 2
    'item_name' => 'bar'
  )
) etc. etc.

I am getting another array from a third party source and need to remove items that are not in my first array.

array(
  [0] => array(
    'item_no' => 1
  )
  [1] => array(
    'item_no' => 100
  ) # should be removed as not in 1st array

How would I search the first array using each item in the second array like (in pseudo code):

if 'item_no' == x is in 1st array continue else remove it from 2nd array.

Upvotes: 0

Views: 581

Answers (3)

Gumbo
Gumbo

Reputation: 655129

If your key is not actually a key of your array but a value, you will probably need to do a linear search:

foreach ($itemsToRemove as $itemToRemove) {
    foreach ($availableItems as $key => $availableItem) {
        if ($itemToRemove['item_no'] === $availableItem['item_no']) {
            unset($availableItems[$key]);
        }
    }
}

It would certainly be easier if item_no is also the key of the array items like:

$availableItems = array(
  123 => array(
    'item_no' => 123,
    'item_name' => 'foo'
  ),
  456 => array(
    'item_no' => 456,
    'item_name' => 'bar'
  )
);

With this you could use a single foreach and delete the items by their keys:

foreach ($itemsToRemove as $itemToRemove) {
    unset($availableItems[$itemToRemove['item_no']]);
}

You could use the following to build an mapping of item_no to your actual array keys:

$map = array();
foreach ($availableItems as $key => $availableItem) {
    $map[$availableItems['item_no']] = $key;
}

Then you can use the following to use the mapping to delete the corresponding array item:

foreach ($itemsToRemove as $itemToRemove) {
    unset($availableItems[$map[$itemToRemove['item_no']]]);
}

Upvotes: 0

codaddict
codaddict

Reputation: 454930

You can also do:

$my_array =array(
  0 => array( 'item_no' => 1,'item_name' => 'foo'),
  1 => array( 'item_no' => 2,'item_name' => 'bar')
);

$thrid_party_array = array(
  0 => array( 'item_no' => 1), 
  1 => array( 'item_no' => 100),
);

$temp = array();  // create a temp array to hold just the item_no
foreach($my_array as $key => $val) {
        $temp[] = $val['item_no'];
}

// now delete those entries which are not in temp array.
foreach($thrid_party_array as $key => $val) {
        if(!in_array($val['item_no'],$temp)) {
                unset($thrid_party_array[$key]);
        }   
}

Working link

Upvotes: 0

Victor Nicollet
Victor Nicollet

Reputation: 24577

// Returns the item_no of an element
function get_item_no($arr) { return $arr['item_no']; }

// Arrays of the form "item_no => position in the array"
$myKeys    = array_flip(array_map('get_item_no', $myArray));
$theirKeys = array_flip(array_map('get_item_no', $theirArray));

// the part of $theirKeys that has an item_no that's also in $myKeys
$validKeys = array_key_intersect($theirKeys, $myKeys);

// Array of the form "position in the array => item_no"
$validPos  = array_flip($validKeys);

// The part of $theirArray that matches the positions in $validPos
$keptData  = array_key_intersect($theirArray, $validPos);

// Reindex the remaining values from 0 to count() - 1
return array_values($keptData);

All of this would be easier if, instead of storing the key in the elements, you stored it as the array key (that is, you'd be using arrays of the form "item_no => item_data") :

// That's all there is to it
return array_key_intersect($theirArray, $myArray);

Upvotes: 1

Related Questions