[英]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.