【问题标题】:How to convert a 2-dim array of strings into 1-dim array of trimmed, unique values?如何将 2-dim 字符串数组转换为 1-dim 修剪的唯一值数组?
【发布时间】:2011-09-12 11:30:07
【问题描述】:

我有一个数组,其值都是特定格式的数组,如下所示:

Array
(
    [0] => Array
        (
            [0] => '8227'
            [1] => ' 8138'
        )

    [1] => Array
        (
            [0] => '8227'
            [1] => ' 8138'
            [2] => ' 7785'
        )

)

我想要这个:

Array
(
    [0] => 8227
    [1] => 8138
    [2] => 7785
)

我该怎么做?

【问题讨论】:

    标签: php arrays foreach unique


    【解决方案1】:
    $result = array();
    foreach ($input as $sub) { // Loop outer array
      foreach ($sub as $val) { // Loop inner arrays
        $val = trim($val);
        if (!in_array($val, $result)) { // Check for duplicates
          $result[] = $val; // Add to result array
        }
      }
    }
    

    【讨论】:

    • @ajreal 不适用于这个特定的任务,只是吐出你输入的内容。
    • 嗯? array_mege_recursive($array[0], $array[1] ...) ?
    • @ajreal 不会删除重复项(尽管之后您可以调用 array_unique()),结果键可能与 array_unique() 调用不连续(尽管您可以通过 array_merge() 传递它)但更重要的是,只有在您确切知道容器数组中有多少子数组时才有效。如果您执行上述所有操作,则比循环方法(在 PHP/5.2.19 上的 win32 上测试超过 10000 次迭代)长约 50%。
    【解决方案2】:
    $result = array();
    foreach($array as $arr){
        $result = array_merge($result, $arr);
    }
    
    $result = array_unique($result);
    

    【讨论】:

    • +1。我喜欢这个,它比我的更整洁,但实际上比 10000 次迭代慢了近两倍。这实际上让我感到惊讶 - 我认为这会更快 - 但就是这样。
    • 如果 id 的开头有空格,它会返回重复值.. 是否有可能克服它...例如,如果 id 8227 中有空格,则使用上述代码返回两次..有什么办法解决吗?
    • @Fero 我已经修改了我的答案,因此它会从 ID 中去除前导/尾随空格,并且不会导致重复。但是,如果空格位于字符串的中间,您最好使用preg_replace() 来摆脱它。
    【解决方案3】:

    array_merge_recursive() 可用于展平阵列。然后,array_unique() 获取唯一值,array_values() 为结果数组“重新索引”。

    $flat = call_user_func_array('array_merge_recursive', $subject);
    $uniq = array_values(array_unique($flat));
    

    【讨论】:

      【解决方案4】:
      <?php
      $array = array(
      0 => array(
          0 => 8227,
          1 => 8138
      ),
      1 => array(
          0 => 8227,
          1 => 8138,
          2 => 7785
      )
      );
      
      $newArray = array();
      array_walk_recursive($array, function($item, $key) use(&$newArray) {
      if(!in_array($item, $newArray)) {
          $newArray[] = $item;
      }
      });
      
      print_r($newArray);
      ?>    
      

      【讨论】:

        【解决方案5】:

        我不喜欢迭代调用 in_array() 的想法,因为它会对大数组造成一点拖累。

        现在,我要遵循的方法可能不会创造任何速度记录(我没有费心进行基准测试),但我想我会发布一些非正统的方法,以防它们可能会激励未来的读者。

        方法#1:

        • 将多维数组转换为json字符串
        • 在所有非数字子字符串上拆分字符串(这也会修剪值)
        • 使用array_flip() 消除重复项
        • 使用 array_keys() 重新索引结果数组(输出值为整数类型)

        方法#2:

        • 将多维数组转换为json字符串
        • 提取单词(在这种情况下包括数字,无需担心任何字母)
        • 使用array_flip() 消除重复项
        • 使用array_keys() 重新索引结果数组(输出值为整数类型)

        代码:(Demo)

        $array = [['8227', '8138'], [' 8227', ' 8138', ' 7785']];
        
        echo "regex method: ";
        
        var_export(
            array_keys(
                array_flip(
                    preg_split(
                        '/\D+/',
                        json_encode($array),
                        0,
                        PREG_SPLIT_NO_EMPTY
                    )
                )
            )
        );
        
        echo "\n\nnon-regex method: ";
        
        var_export(
            array_keys(
                array_flip(
                    str_word_count(
                        json_encode($array),
                        1,
                        '0..9'
                    )
                )
            )
        );
        

        输出:

        regex method: array (
          0 => 8227,
          1 => 8138,
          2 => 7785,
        )
        
        non-regex method: array (
          0 => 8227,
          1 => 8138,
          2 => 7785,
        )
        

        如果这两种方法中的任何一种表现良好,那是因为它们没有进行迭代函数调用。

        附言好吧,因为我很好奇,我只是对我的两种方法和 DaveRandom 的方法做了一个非常小的/非官方的速度测试(使用 OP 的数据只有 1000 次迭代 - 我不想滥用 3v4l.org)和...

        • 方法 #1 的运行速度与方法 #2 差不多
        • 方法 #1 和方法 #2 的运行速度都比 DaveRandom 的方法快。

        我再次声明,针对微优化的捏造测试可能毫无意义,如果实际数据确实很重要,则应该对您的真实数据进行真实测试。如果您只是更喜欢此页面上另一个答案的逻辑流程,我完全尊重这一点。

        【讨论】:

          猜你喜欢
          • 2018-11-08
          • 2021-06-18
          • 1970-01-01
          • 2022-12-11
          • 1970-01-01
          • 2021-04-09
          • 1970-01-01
          • 2011-02-05
          • 2015-06-16
          相关资源
          最近更新 更多