如何将字符串数组转换为具有可变块大小的块数组?

时间:2018-11-03 01:00:14

标签: php arrays data-structures

一个人如何转换以下数组:

[
  "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如果不是因为这些块具有可变大小的事实,那将是完美的选择。前缀是提前知道的,每个“块”的长度为两个或三个。

4 个答案:

答案 0 :(得分: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;
}

假定应该以相同的子数组结尾的键在输入中按字母顺序排列,因此当不保持此顺序时,会进入下一个子数组。

答案 1 :(得分:1)

此解决方案允许将前缀按任意顺序排序,方法是将前缀按预期在输入数据中遇到的顺序存储在数组中(假定在$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

答案 2 :(得分:1)

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',
  ),
)

答案 3 :(得分:1)

您可以轻松一点

$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