【问题标题】:How do I remove a specific key in an array using php?如何使用 php 删除数组中的特定键?
【发布时间】:2012-01-02 06:46:14
【问题描述】:

我有一个包含 4 个值的数组。我想删除第二个位置的值,然后让其余的键向下移动一个。

$b = array(123,456,789,123);

在移除第二个位置的钥匙之前:

数组([0] => 123 [1] => 456 [2] => 789 [3] => 123)

在我希望剩余的键向下移动一个以填充缺少的键的空间之后

数组([0] => 123 [1] => 789 [2] => 123)

我尝试在特定键上使用 unset(),但它不会向下移动其余键。如何使用 php 删除数组中的特定键?

【问题讨论】:

标签: php arrays


【解决方案1】:

表示您的输入数据是一个索引数组(从零开始的整数键的序列中没有间隙)。我将比较直接从 OP 的样本数据中提供所需结果的明显技术。

1。 unset() 然后array_values()

unset($b[1]);
$b = array_value($b);
  • 无需检查索引是否存在即可安全使用 - 如果缺失,则不会出错。
  • unset() 可以接收多个参数,所以如果需要移除更多元素,那么函数调用的次数保持不变。例如unset($b[1], $b[3], $b[5]);
  • unset() 不能嵌套在 array_values() 内部以形成单行,因为 unset() 修改了变量并且不返回任何值。
  • AFAIK,unset() 对于使用动态白名单/黑名单键删除元素并不是特别方便。

2。 array_splice()

array_splice($b, 1, 1);
//          (input array, starting position, number of elements to remove)
  • 此函数是键无知的,它将根据元素在数组中的位置来定位元素。无需检查位置是否存在即可安全使用 - 如果缺失,则不会出错。
  • array_splice() 可以删除单个元素,或者最多删除多个连续元素。如果您需要删除不连续的元素,则需要进行额外的函数调用。
  • array_splice() 不需要 array_values() 调用,因为“输入中的数字键未保留”——在某些情况下,这可能是可取的,也可能是不可取的。

3。 array_filter() 嵌套在 array_values()

array_values(
    array_filter(
        $b,
        function($k) {
            return $k != 1;
        },
        ARRAY_FILTER_USE_KEY
    )
)
  • 这种技术依赖于自定义函数调用和一个标志来告诉过滤器只迭代键。
  • 它将是一个相对较差的性能,因为它迭代所有元素而不考虑逻辑必要性。
  • 这是我将讨论的选项中最冗长的选项。
  • 如果您想在自定义函数中使用带有白名单/黑名单键的 in_array() 调用,则会进一步降低效率。
  • 在 PHP7.4 之前,将白名单/黑名单/变量传递到自定义函数范围将需要使用 use()
  • 可以写成单行。
  • 无需检查索引是否存在即可安全使用 - 如果缺少索引,则不会出现错误。

4。 array_diff_key() 嵌套在 array_values()

array_values(
    array_diff_key(
        $b,
        [1 => '']
    )
);
  • 这种技术并不是非常冗长,但如果您只需要删除一个元素,它就有点过头了。
  • array_diff_key() 当有一个白名单/黑名单的键数组(可能有不同的元素数)时,真的会发光。 PHP 在处理键方面非常迅速,所以这个函数在它设计的任务中非常有效。
  • 数组中被声明为array_diff_key() 的第二个参数的值是完全不相关的——它们可以是null999'eleventeen'——只考虑键。
  • array_filter() 相比,array_diff_key() 没有任何范围界定挑战,因为没有调用自定义函数。
  • 可以写成单行。
  • 无需检查索引是否存在即可安全使用 - 如果缺失,则不会出现错误。

【讨论】:

    【解决方案2】:

    没有人提到这一点,所以我会这样做:sort() 是你的朋友。

    $fruits = array("lemon", "orange", "banana", "apple");
    sort($fruits);
    foreach($fruits as $key => $val)
      echo "fruits[$key] = $val";
    

    输出:

    fruits[0] = apple
    
    fruits[1] = banana
    
    fruits[2] = lemon
    
    fruits[3] = orange
    
    // remove Lemon, too bitter
    unset($fruits[2]);
    // keep keys with asort
    asort($fruits);
    foreach($fruits as $key => $val)
      echo "fruits[$key] = $val";
    

    输出:

    fruits[0] = apple
    
    fruits[1] = banana
    
    fruits[3] = orange
    

    这是您要用来重新索引键的那个:

    // reindex keys with sort
    sort($fruits);
    foreach($fruits as $key => $val)
      echo "fruits[$key] = $val";
    

    输出:

    fruits[0] = apple
    
    fruits[1] = banana
    
    fruits[2] = orange
    

    【讨论】:

    • 这个答案在不会通过扰乱元素顺序而损坏输出的情况下非常有限。我担心这种技术弊大于利。
    【解决方案3】:

    如果你想从数组中的特定位置移除一个项目,你可以获取该位置的键,然后取消设置:

    $b = array(123,456,789,123);
    $p = 2;
    $a = array_keys($b);
    if ($p < 0 || $p >= count($a))
    {
        throw new RuntimeException(sprintf('Position %d does not exists.', $p));
    }
    $k = $a[$p-1];
    unset($b[$k]);
    

    这适用于任何 PHP 数组,无论索引从哪里开始或字符串是否用于键。

    如果您想对剩余的数组重新编号,只需使用array_values

    $b = array_values($b);
    

    这将为您提供一个从零开始的数字索引数组。

    如果原始数组也是从零开始的数字索引数组(如您的问题),您可以跳过有关获取密钥的部分:

    $b = array(123,456,789,123);
    $p = 2;
    if ($p < 0 || $p >= count($b))
    {
        throw new RuntimeException(sprintf('Position %d does not exists.', $p));
    }
    unset($b[$p-1]);
    $b = array_values($b);
    

    或者直接使用array_splice处理偏移量而不是键并且重新索引数组(输入中的数字键不保留):

    $b = array(123,456,789,123);
    $p = 2;
    if ($p < 0 || $p >= count($b))
    {
        throw new RuntimeException(sprintf('Position %d does not exists.', $p));
    }
    array_splice($b, $p-1, 1);
    

    【讨论】:

      【解决方案4】:

      您需要array_values($b) 才能重新键入数组,以便键是连续的和数字的(从 0 开始)。

      以下应该可以解决问题:

      $b = array(123,456,789,123);
      unset($b[1]);
      $b = array_values($b);
      echo "<pre>"; print_r($b);
      

      【讨论】:

      • +1 : 如果你打算让它变得动态,只需添加一个检查:array_key_exists :)
      • 没有理由为此任务调用array_key_exists()。如果你告诉 php 给unset($b[9999999]),它会默默地取消设置——检查没有任何好处。 @无名
      【解决方案5】:

      使用array_splice()

      array_splice( $b, 1, 1 );
      // $b == Array ( [0] => 123 [1] => 789 [2] => 123 )
      

      【讨论】:

        猜你喜欢
        • 2014-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-09
        • 1970-01-01
        • 1970-01-01
        • 2020-05-26
        • 2011-01-27
        相关资源
        最近更新 更多