简体   繁体   English

PHP:将数据与来自单个阵列的共享密钥组合到新阵列中

[英]PHP: Combining data with a shared key from a single array into new array

I have this array: 我有这个数组:

array(5) {
  [0]=>
  array(4) {
    ["productCode"]=>
    string(4) "X001"
    ["productUPC"]=>
    string(3) "261"
    ["productTextSeq"]=>
    string(1) "1"
    ["productTxtVal"]=>
    string(5) "Text1"
   }
  [1]=>
  array(4) {
    ["productCode"]=>
    string(4) "X001"
    ["productUPC"]=>
    string(3) "261"
    ["productTextSeq"]=>
    string(1) "2"
    ["productTxtVal"]=>
    string(5) "Text2"
   }
  [2]=>
  array(4) {
    ["productCode"]=>
    string(4) "X001"
    ["productUPC"]=>
    string(3) "261"
    ["productTextSeq"]=>
    string(1) "3"
    ["productTxtVal"]=>
    string(5) "Text3"
   }
  [3]=>
  array(4) {
    ["productCode"]=>
    string(4) "X002"
    ["productUPC"]=>
    string(3) "262"
    ["productTextSeq"]=>
    string(1) "1"
    ["productTxtVal"]=>
    string(5) "Text1"
   }
  [4]=>
  array(4) {
    ["productCode"]=>
    string(4) "X002"
    ["productUPC"]=>
    string(3) "262"
    ["productTextSeq"]=>
    string(1) "2"
    ["productTxtVal"]=>
    string(5) "Text2"
   }
}

With the above input, I want the output array to look like this: 通过上面的输入,我希望输出数组看起来像这样:

array(2) {
  [0]=>
  array(3) {
    ["productCode"]=>
    string(4) "X001"
    ["productUPC"]=>
    string(3) "261"
    ["productTxtVal"]=>
    string(17) "Text1 Text2 Text3"
   }
  [1]=>
  array(3) {
    ["productCode"]=>
    string(4) "X002"
    ["productUPC"]=>
    string(3) "262"
    ["productTxtVal"]=>
    string(11) "Text1 Text2"
   }
}

The resulting array does not need the productTextSeq key, just the combined values of productTextVal, when the productCode is the same. 当productCode相同时,结果数组不需要productTextSeq键,只需要productTextVal的组合值。 I've searched SO for examples of this but it seems every example I've found are based on multiple input arrays. 我搜索了SO的例子,但似乎我发现的每个例子都基于多个输入数组。 I know I can brute force this with nested foreach functions but would love a more elegant solution. 我知道我可以通过嵌套的foreach函数来强制使用它,但是我会喜欢更优雅的解决方案。

I ended up just doing it the brute force method, here is my solution if anyone's interested: 我最后只是做了蛮力方法,如果有人感兴趣,这是我的解决方案:

$productData = array();
$sortedData = array();
$comments = '';
$saveKey = '';
$appendComment = false;
$idx = 0;

foreach ($data as $key=>$value) {

    foreach ($value as $k=>$v) {
        if ($k == 'productCode') {
            if ($v == $saveKey) {
                $appendComment = true;
            } else {
                $appendComment = false;
                $saveKey = $v;
                if ($idx !== 0) { // Don't write to array on first iteration!
                    $productData['productTxtVal'] = $comments;
                    $sortedData[] = $productData;
                }
            }
        }

        if ($k == 'productTxtVal') {
            if ($appendComment == true) {
                $comments .= ' ' . trim($v);
            } else {
                $comments = trim($v);
            }
        }
    }

    $productData = $value;
    $idx++;
}

Not "elegant" but it works. 不是“优雅”,但它的工作原理。 I also have a check after this logic in case only one productCode is in the original array, as it won't be written to the $sortedData array since the key never changes. 我也检查了这个逻辑,以防只有一个productCode在原始数组中,因为它不会被写入$ sortedData数组,因为密钥永远不会改变。

The following code assumes you control the contents of the original data array (due to risk of injection using extract() function) and that no 2 items with the same productCode have the same productTextSeq . 以下代码假定您控制原始数据数组的内容(由于使用extract()函数注入的风险)并且没有2个具有相同productCode项具有相同的productTextSeq

$products = [];
foreach ($data as $item) {
    // extract contents of item array into variables
    extract($item);
    if (!isset($products[$productCode])) {
        // create product array with code, upc, text as array
        $products[$productCode] = compact('productCode', 'productUPC') + ['productTxtVal' => []];
    }
    // add text value to array with sequence as index
    $products[$productCode]['productTxtVal'][$productTextSeq] = $productTxtVal;
}

$products = array_values( // ignore array keys
    array_map(function($product) {
        ksort($product['productTxtVal']); // sort text as array by index/ sequence
        $product['productTxtVal'] = implode(' ', $product['productTxtVal']); // implode into string
        return $product;
    }, $products)
);

You can run the code here: https://repl.it/BWQL 您可以在此处运行代码: https//repl.it/BWQL

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM