【问题标题】:How to convert array of strings to an array of chunks with variable chunk sizes?如何将字符串数组转换为具有可变块大小的块数组?
【发布时间】:2018-11-03 01:00:13
【问题描述】:

如何转换以下数组:

[
  "prefix1 foo",
  "prefix2 bar",
  "prefix1 aaa",
  "prefix2 bbb",
  "prefix3 ccc",
  "prefix1 111",
  "prefix2 222"
]

进入如下数据结构:

[
  [
    "prefix1" => "foo",
    "prefix2" => "bar"
  ],
  [
    "prefix1" => "aaa",
    "prefix2" => "bbb",
    "prefix3" => "ccc"
  ],
  [
    "prefix1" => "111",
    "prefix2" => "222"
  ],
]

array_chunk 如果不是因为块的大小可变,那将是完美的。前缀是提前知道的,每个“块”的长度为 2 或 3。

【问题讨论】:

  • 循环和explode(),然后用碎片构建一个新数组
  • 以后请包括你最好的失败的编码尝试。

标签: php arrays data-structures


【解决方案1】:

你可以这样做(给定$input):

$result = [];
$prev = $input[0];
foreach($input as $line) {
    list($key, $value) = explode(" ", $line);
    if ($key < $prev) $result[] = [];
    $result[count($result)-1][$key] = $value;
    $prev = $key;
}

假设应该在同一个子数组中结束的键在输入中按字母顺序排列,因此当不保持此顺序时会中断到下一个子数组。

【讨论】:

    【解决方案2】:

    此解决方案允许前缀任意排序,方法是按照预期在输入数据中遇到的顺序将它们存储在一个数组中(假设在$input):

    $prefixes = ['prefix1', 'prefix2', 'prefix3'];
    $output = array();
    $lastidx = count($prefixes);
    foreach ($input as $item) {
        list($prefix, $value) = explode(' ', $item);
        $index = array_search($prefix, $prefixes);
        if ($index < $lastidx) $output[] = array();
        $output[count($output)-1][$prefix] = $value;
        $lastidx = $index;
    }
    print_r($output);
    

    对于您的示例输入输出是:

    Array ( 
        [0] => Array ( 
            [prefix1] => foo
            [prefix2] => bar 
        )
        [1] => Array (
            [prefix1] => aaa
            [prefix2] => bbb
            [prefix3] => ccc
        )
        [2] => Array (
            [prefix1] => 111
            [prefix2] => 222
        ) 
    )
    

    Demo on 3v4l.org

    【讨论】:

      【解决方案3】:

      isset()array_search()

      代码:(Demo)

      $array = [
        "prefix1 foo",
        "prefix2 bar",
        "prefix1 aaa",
        "prefix2 bbb",
        "prefix3 ccc",
        "prefix1 111",
        "prefix2 222"
      ];
      
      foreach ($array as $v) {
          [$prefix, $value] = explode(' ', $v, 2);  // explode and perform "array destructuring"
          if (isset($batch[$prefix])) {     // check if starting new batch
              $result[] = $batch;           // store old batch
              $batch = [$prefix => $value]; // start new batch
          } else{
              $batch[$prefix] = $value;     // store to current batch
          }
      }
      $result[] = $batch;                   // store final batch
      var_export($result);
      

      foreach ($array as $v) {
          [$prefix, $value] = explode(' ', $v, 2);
          if (isset($batch[$prefix])) {
              $result[] = $batch;
              unset($batch);
          }
          $batch[$prefix] = $value;
      }
      $result[] = $batch;
      

      输出:

      array (
        0 => 
        array (
          'prefix1' => 'foo',
          'prefix2' => 'bar',
        ),
        1 => 
        array (
          'prefix1' => 'aaa',
          'prefix2' => 'bbb',
          'prefix3' => 'ccc',
        ),
        2 => 
        array (
          'prefix1' => '111',
          'prefix2' => '222',
        ),
      )
      

      【讨论】:

        【解决方案4】:

        你可以轻松一点

        $res = [];
        foreach ($array as $v) {
            list($prefix, $value) = explode(' ', $v, 2);
            $res[$prefix][] = [$prefix => $value];
        }
        print_r($res);
        // if you want numeric index
        $res = array_values($res);
        print_r($res);
        

        demo

        【讨论】:

          猜你喜欢
          • 2013-04-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-14
          • 2019-07-15
          • 2021-12-13
          • 2018-07-04
          • 2019-05-27
          相关资源
          最近更新 更多