开发者

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 ar开发者_开发百科ray

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.


// 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);


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


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']]]);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜