我想组合具有相同类别id和问题id的数组。
样本输入:
$array = [
[
'category_id' => 1,
'question_id' => 1,
'option_id' => 2,
'title' => 'Do you wear glasses?',
'answer' => 'no'
],
[
'category_id' => 1,
'question_id' => 2,
'option_id' => 3,
'title' => 'Your hobbies ?',
'answer' => 'movies'
],
[
'category_id' => 1,
'question_id' => 4,
'option_id' => 8,
'title' => 'what is your status?',
'answer' => 'single'
],
[
'category_id' => 1,
'question_id' => 2,
'option_id' => 1,
'title' => 'Your hobbies ?',
'answer' => 'travel'
],
];
第二个和第四个数组包含相同的问题(相同的类别id和相同的问题id(,所以我希望将它们的答案值合并为逗号分隔的字符串。
期望结果:
Array(
[0] => Array
(
[category_id] => 1
[question_id] => 1
[option_id] => 2
[title] => Do you wear glasses?
[answer] => no
)
[1] => Array
(
[category_id] => 1
[question_id] => 2
[option_id] => 3
[title] => Your hobbies ?
[answer] => movies,travel
)
[2] => Array
(
[category_id] => 1
[question_id] => 4
[option_id] => 8
[title] => what is your status?
[answer] => single
)
)
分组时可以覆盖选项id和标题,因为我没有使用选项id,并且每个组中的标题值都是相同的。
也许这样的东西可以工作,不确定是否有更好的方法来实现:
new_array=array();
foreach($source_array as $e){
$insert=1;
foreach($new_array as $n)
if(array_search($e['title'], $n)==false){
$n['answer'].=", ".$e['answer'];
$insert=0;
}
}
if($insert){
$new_array[]=$e;
}
}
例如数组
Array
(
[0] => Array
(
[category_id] => 1
[question_id] => 1
)
[1] => Array
(
[category_id] => 2
[question_id] => 2
)
[2] => Array
(
[category_id] => 1
[question_id] => 1
)
)
你可以做这样的事情作为的插图
// Define the array to work on
$array = array( array( 'category_id' => 1, 'question_id'=> 1), array( 'category_id' => 2, 'question_id' => 2), array( 'category_id' => 1, 'question_id' => 1));
// Initialize the result array containing only unique question_id/category_id combinations
$unique_array = array();
foreach ($array as $key) {
if (!count($unique_array)) {
$unique_array[] = $key;
} else {
$unique = 1;
foreach ($unique_array as $check) {
if ( $check['category_id'] == $key['category_id'] && $check['question_id'] == $key['question_id'] ) {
$unique = 0;
}
}
if ( $unique ) {
$unique_array[] = $key;
}
}
}
print_r($unique_array);
最后一次print_r的输出将是
Array
(
[0] => Array
(
[category_id] => 1
[question_id] => 1
)
[1] => Array
(
[category_id] => 2
[question_id] => 2
)
)
我问顺序是否重要的原因是,如果顺序无关紧要,你可以先对数组进行排序,然后只将每个数组与其前一个同级数组进行比较:
$source=array(array("cat_id"=>1,"ques_id"=>1,"opt_id"=>2,"title"=>"cid:1, qid:1, oid:2","answer"=>"whatever"),array("cat_id"=>1,"ques_id"=>2,"opt_id"=>3,"title"=>"cid:1, qid:2, oid:3","answer"=>"whatever"),array("cat_id"=>1,"ques_id"=>4,"opt_id"=>8,"title"=>"cid:1, qid:4, oid:8","answer"=>"whatever"),array("cat_id"=>1,"ques_id"=>2,"opt_id"=>1,"title"=>"cid:1, qid:2, oid:1","answer"=>"whtvr"));
print_r($source); // just to debug
usort($source,function($a,$b){
if($a["cat_id"]<$b["cat_id"])
return -1;
elseif($a["cat_id"]>$b["cat_id"])
return 1;
elseif($a["ques_id"]<$b["ques_id"])
return -1;
elseif($a["ques_id"]>$b["ques_id"])
return 1;
elseif($a["opt_id"]<$b["opt_id"])
return -1;
elseif($a["opt_id"]>$b["opt_id"])
return 1;
else
return 0;
});
$source=array_reduce($source,function(&$a,$b){
if(empty($a))
{
$a=array($b);
}
else
{
$cache=array_pop($a);
if($cache["cat_id"]==$b["cat_id"] && $cache["ques_id"]==$b["ques_id"])
{
$cache["answer"].=", ".$b["answer"];
$a[]=$cache;
}
else
{
$a[]=$cache;
$a[]=$b;
}
}
return $a;
},array());
print_r($source);
输出:
// first print_r
Array
(
[0] => Array
(
[cat_id] => 1
[ques_id] => 1
[opt_id] => 2
[title] => cid:1, qid:1, oid:2
[answer] => whatever
)
[1] => Array
(
[cat_id] => 1
[ques_id] => 2
[opt_id] => 3
[title] => cid:1, qid:2, oid:3
[answer] => whatever
)
[2] => Array
(
[cat_id] => 1
[ques_id] => 4
[opt_id] => 8
[title] => cid:1, qid:4, oid:8
[answer] => whatever
)
[3] => Array
(
[cat_id] => 1
[ques_id] => 2
[opt_id] => 1
[title] => cid:1, qid:2, oid:1
[answer] => whtvr
)
)
// second print_r
Array
(
[0] => Array
(
[cat_id] => 1
[ques_id] => 1
[opt_id] => 2
[title] => cid:1, qid:1, oid:2
[answer] => whatever
)
[1] => Array
(
[cat_id] => 1
[ques_id] => 2
[opt_id] => 1
[title] => cid:1, qid:2, oid:1
[answer] => whtvr, whatever
)
[2] => Array
(
[cat_id] => 1
[ques_id] => 4
[opt_id] => 8
[title] => cid:1, qid:4, oid:8
[answer] => whatever
)
)
请注意,您在评论中表示option_id
无关紧要,因此我没有替换它;如果需要,也可以在array_reduce
内部的匿名函数中替换它。
$data = array();
//$new is the array in which you have data originally
foreach($new as $arrayK => $arrayV){
if(!isset($data[$arrayV['category_id']][$arrayV['question_id']]))
$data[$arrayV['category_id']][$arrayV['question_id']] = $arrayV;
else{
$option = $data[$arrayV['category_id']][$arrayV['question_id']]['option_id'] . ',' . $arrayV['option_id'];
$data[$arrayV['category_id']][$arrayV['question_id']]['option_id'] = $option;
$answer = $data[$arrayV['category_id']][$arrayV['question_id']]['answer'] . ',' . $arrayV['answer'];
$data[$arrayV['category_id']][$arrayV['question_id']]['answer'] = $answer;
}
}
$data将具有上述格式的所需数据
答案和选项都将是逗号分隔的
foreach($arr as $k=>$a)
{
$common[$k] = search($arr,'category_id',$a['category_id'],'question_id',$a['question_id']);
$answers = array_map(function($item) { return $item['answer']; }, $common[$k]);
$options = array_map(function($item) { return $item['option_id']; }, $common[$k]);
foreach($common[$k] as $temp)
{
$finalAns = $temp;
$finalAns['answer'] = implode(",",$answers);
$finalAns['option_id'] = implode(",",$options);
}
$final[] = $finalAns;
}
$final = array_map("unserialize", array_unique(array_map("serialize", $final)));
echo "<pre>";
print_r($final);
将Below函数放在您的通用函数文件中或同一文件中。
function search($array, $key, $value, $key1, $value1)
{
$results = array();
if (is_array($array))
{
if (isset($array[$key]) && $array[$key] == $value && isset($array[$key1]) && $array[$key1] == $value1)
{
$results[] = $array;
}
foreach ($array as $subarray)
$results = array_merge($results, search($subarray, $key, $value,$key1,$value1));
}
return $results;
}
你的输出将是
阵列([0]=>数组([category_id]=>1[question_id]=>1[option_id]=>2[title]=>你戴眼镜吗?[答案]=>否)
[1] => Array
(
[category_id] => 1
[question_id] => 2
[option_id] => 3,1
[title] => Your hobbies ?
[answer] => movies,travel
)
[2] => Array
(
[category_id] => 1
[question_id] => 4
[option_id] => 8
[title] => what is your status?
[answer] => single
)
)
没有理由使用复杂的逻辑或多个循环。
每个组都需要有一个唯一的标识符。尽管asker声明question_id
就足够了,但您可以通过将question_id
和category_id
组合为分隔字符串来保证唯一性。使用这个";复合标识符";作为第一级关键字,同时将数据推入结果数组。
当再次遇到复合键时(,不要同时保存所有数据——只将数据附加到所需的元素。
迭代完成后,重新索引结果数组以移除临时复合键(如果愿意(。
代码:(演示(
$result = [];
foreach ($array as $row) {
$compositeKey = $row['category_id'] . '_' . $row['question_id'];
if (!isset($result[$compositeKey])) {
$result[$compositeKey] = $row;
} else {
$result[$compositeKey]['answer'] .= ",{$row['answer']}";
}
}
var_export(
array_values(
$result
)
);
附言:通常,最好形成子数组,而不是逗号分隔的字符串。子数组允许更好地访问单个值,并在表示中具有灵活性。如果你改变了如何显示值的想法,那么你需要删除或替换逗号,并打印其他内容。省去麻烦,将演示留给您的(视图(演示循环,并按照您的意愿内爆子数组值。