【问题标题】:Rebase array keys after unsetting elements [duplicate]取消设置元素后重新排列数组键[重复]
【发布时间】:2011-08-22 00:54:28
【问题描述】:

我有一个数组:

$array = array(1,2,3,4,5);

如果我要转储数组的内容,它们将如下所示:

array(5) {
  [0] => int(1)
  [1] => int(2)
  [2] => int(3)
  [3] => int(4)
  [4] => int(5)
}

当我循环遍历并取消设置某些键时,索引会全部被提升。

foreach($array as $i => $info)
{
  if($info == 1 || $info == 2)
  {
    unset($array[$i]);
  }
}

随后,如果我现在进行另一个转储,它会如下所示:

array(3) {
  [2] => int(3)
  [3] => int(4)
  [4] => int(5)
}

是否有正确的方法来重置数组,使其元素再次基于零?

array(3) {
  [0] => int(3)
  [1] => int(4)
  [2] => int(5)
}

【问题讨论】:

    标签: php


    【解决方案1】:

    试试这个:

    $array = array_values($array);
    

    使用array_values()

    【讨论】:

    • +1。我注意到手册没有明确说明将保持顺序,但我不明白为什么不会。
    • 是的,订单肯定是维持的。如果它重新排序将是一个可怕的功能! :)
    • @webbiedave 抱歉,但事实并非如此。它实际上对我的数组进行了重新排序。非常非常奇怪。
    • 总是选择简单简洁的解决方案 :)
    • 虽然当数组已经编号时这是一个简单的解决方案,但当键设置为文本时它不起作用,就像它作为 HTML 表单的一部分一样。如果您依靠唯一键值来识别表单的输出,则以下方法之一效果更好。
    【解决方案2】:

    还有一个有趣的方法:

    $array = array('a', 'b', 'c', 'd'); 
    unset($array[2]); 
    
    $array = array_merge($array); 
    

    现在 $array 键被重置了。

    【讨论】:

      【解决方案3】:

      使用array_splice 而不是unset

      $array = array(1,2,3,4,5);
      foreach($array as $i => $info)
      {
        if($info == 1 || $info == 2)
        {
          array_splice($array, $i, 1);
        }
      }
      
      print_r($array);
      

      Working sample here.

      【讨论】:

      • 这不起作用。 splice 会很棒,但是您不能在 for/foreach 循环中使用它,因为它每次调用它时都会重新排列索引,因此 foreach 循环的索引不指向下一个元素,而是指向具有该位置的元素在重新排列的阵列上。您可以在示例中看到您正在删除值“3”并保留值“2”,而您应该只删除值“1”和“2”
      • @elcodedocle 然后不要使用foreach 循环。使用标准 i Loop 并在拼接后简单地重置 i 。此外,Working sample here. 不起作用。
      • 链接断开,你能修复它吗?
      【解决方案4】:

      只是一种添加剂。

      我知道这是,但我想添加一个我自己没有想到的解决方案。在寻找不同的解决方案时发现了这个问题,只是想,“好吧,当我在这里的时候。”

      首先,Neal 的答案很好,在您运行循环后非常适合使用,但是,我更喜欢一次完成所有工作。当然,在我的具体情况下,我必须比这里的这个简单示例做 更多 工作,但该方法仍然适用。我看到其他几个人建议 foreach 循环,但是,由于野兽的性质,这仍然让您下班。通常我建议像foreach 这样更简单的东西,但是,在这种情况下,最好记住老式的for loop 逻辑。只需使用 i!要保持适当的索引,只需在每次删除 Array 项后从 i 中减去。

      这是我的简单工作示例:

      $array = array(1,2,3,4,5);
      
      for ($i = 0; $i < count($array); $i++) {
          if($array[$i] == 1 || $array[$i] == 2) {
              array_splice($array, $i, 1);
              $i--;
          }
      }
      

      将输出:

      array(3) {
          [0]=> int(3)
          [1]=> int(4)
          [2]=> int(5)
      }
      

      这可以有很多简单的实现。例如,我的确切情况需要根据多维值在数组中保存最新项目。我会告诉你我的意思:

      $files = array(
          array(
              'name' => 'example.zip',
              'size' => '100000000',
              'type' => 'application/x-zip-compressed',
              'url' => '28188b90db990f5c5f75eb960a643b96/example.zip',
              'deleteUrl' => 'server/php/?file=example.zip',
              'deleteType' => 'DELETE'
          ),
          array(
              'name' => 'example.zip',
              'size' => '10726556',
              'type' => 'application/x-zip-compressed',
              'url' => '28188b90db990f5c5f75eb960a643b96/example.zip',
              'deleteUrl' => 'server/php/?file=example.zip',
              'deleteType' => 'DELETE'
          ),
          array(
              'name' => 'example.zip',
              'size' => '110726556',
              'type' => 'application/x-zip-compressed',
              'deleteUrl' => 'server/php/?file=example.zip',
              'deleteType' => 'DELETE'
          ),
          array(
              'name' => 'example2.zip',
              'size' => '12356556',
              'type' => 'application/x-zip-compressed',
              'url' => '28188b90db990f5c5f75eb960a643b96/example2.zip',
              'deleteUrl' => 'server/php/?file=example2.zip',
              'deleteType' => 'DELETE'
          )
      );
      
      for ($i = 0; $i < count($files); $i++) {
          if ($i > 0) {
              if (is_array($files[$i-1])) {
                  if (!key_exists('name', array_diff($files[$i], $files[$i-1]))) {
                      if (!key_exists('url', $files[$i]) && key_exists('url', $files[$i-1])) $files[$i]['url'] = $files[$i-1]['url'];
                      $i--;
                      array_splice($files, $i, 1);
                  }
              }
          }
      }
      

      将输出:

      array(1) {
          [0]=> array(6) {
                  ["name"]=> string(11) "example.zip"
                  ["size"]=> string(9) "110726556"
                  ["type"]=> string(28) "application/x-zip-compressed"
                  ["deleteUrl"]=> string(28) "server/php/?file=example.zip"
                  ["deleteType"]=> string(6) "DELETE"
                  ["url"]=> string(44) "28188b90db990f5c5f75eb960a643b96/example.zip"
              }
          [1]=> array(6) {
                  ["name"]=> string(11) "example2.zip"
                  ["size"]=> string(9) "12356556"
                  ["type"]=> string(28) "application/x-zip-compressed"
                  ["deleteUrl"]=> string(28) "server/php/?file=example2.zip"
                  ["deleteType"]=> string(6) "DELETE"
                  ["url"]=> string(45) "28188b90db990f5c5f75eb960a643b96/example2.zip"
              }
      }
      

      如您所见,我在拼接之前操纵了 $i,因为我试图删除前一个项目,而不是当前项目。

      【讨论】:

      • 完美的解决方案splice 用于非常大的数组,因为不需要复制。所以我没有记忆问题。
      【解决方案5】:

      我使用$arr = array_merge($arr); 对数组进行变基。简单明了。

      【讨论】:

        【解决方案6】:

        100% 为我工作!在数组中取消设置元素后,您可以使用它来重新索引数组

        $result=array_combine(range(1, count($your_array)), array_values($your_array));
        

        【讨论】:

          【解决方案7】:

          迟到的答案,但是 PHP 5.3 之后可能会这样;

          $array = array(1, 2, 3, 4, 5);
          $array = array_values(array_filter($array, function($v) {
              return !($v == 1 || $v == 2);
          }));
          print_r($array);
          

          【讨论】:

            【解决方案8】:

            或者您可以创建自己的函数,通过引用传递数组。

            function array_unset($unsets, &$array) {
              foreach ($array as $key => $value) {
                foreach ($unsets as $unset) {
                  if ($value == $unset) {
                    unset($array[$key]);
                    break;
                  }
                }
              }
              $array = array_values($array);
            }
            

            那么你所要做的就是……

            $unsets = array(1,2);
            array_unset($unsets, $array);
            

            ...现在您的 $array 没有您在 $unsets 中放置的值,并且密钥已重置

            【讨论】:

              【解决方案9】:

              在我的情况下,我需要为数组值保留唯一键,所以我只使用了第二个数组:

              $arr1 = array("alpha"=>"bravo","charlie"=>"delta","echo"=>"foxtrot");
              unset($arr1);
              
              $arr2 = array();
              foreach($arr1 as $key=>$value) $arr2[$key] = $value;
              $arr1 = $arr2
              unset($arr2);
              

              【讨论】:

              • 1) 你 unset($arr1) 这将使它无法在你的循环中迭代。 2)您在倒数第二行缺少分号。这段代码 sn -p 不会运行。
              猜你喜欢
              • 2015-02-01
              • 2012-12-18
              • 1970-01-01
              • 2011-03-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-09-21
              • 2013-10-23
              相关资源
              最近更新 更多