在PHP中按键匹配数组值

时间:2010-10-13 16:41:01

标签: php arrays

我有一系列项目:

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

我从第三方来源获取另一个数组,需要删除不在我的第一个数组中的项目。

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

如何使用第二个数组中的每个项目搜索第一个数组,如(伪代码):

如果'item_no'== x在第一个数组中,则继续将其从第二个数组中删除。

3 个答案:

答案 0 :(得分:1)

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

如果不将密钥存储在元素中,而是将其存储为数组键(也就是说,您将使用“item_no =&gt; item_data”形式的数组),那么所有这一切都会更容易:< / p>

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

答案 1 :(得分:0)

如果您的密钥实际上不是数组的键而是值,则可能需要进行线性搜索:

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

如果 item_no 也是数组项的键,那肯定会更容易:

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

使用此功能,您可以使用单个foreach并按键删除项目:

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

您可以使用以下内容构建 item_no 到实际数组键的映射:

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

然后您可以使用以下命令来删除相应的数组项:

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

答案 2 :(得分:0)

你也可以这样做:

$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