tags:

views:

41

answers:

3

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.

+1  A: 

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']]]);
}
Gumbo
+1  A: 
// 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);
Victor Nicollet
+1  A: 

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

codaddict
@codaddict Thank you very much, this one is very suitable for my application, especially as I need an array of 'item_no' later on anyway.
esryl