Подсчет вхождений в массиве с более чем 1 ключом

Я пытаюсь получить вхождения массива, принимающего значение ключа 1, например:

 $newarray[0] = [
'id' => '2',
'date' => '2016-04-22'
];
$newarray[1] = [
'id' => '2',
'date' => '2016-04-13'
];
$newarray[2] = [
'id' => '2',
'date' => '2016-04-12'
];
$newarray[3] = [
'id' => '1',
'date' => '2016-03-11'
];
$newarray[4] = [
'id' => '2',
'date' => '2016-03-05'
];
$newarray[5] = [
'id' => '1',
'date' => '2016-03-01'
];

Я хочу преобразовать это в нечто подобное:

Array ( [0] => Array ( [id] => 1 [date] => 2016-03-11 [occurences] => 2 ) [1] => Array ( [id] => 2 [date] => 2016-04-22 [occurences] => 4 )  )

Я пытался сделать это:

$cleanarray;
$newarray2=$newarray;
$newarray;
$k=0;
$num=1;

for($i=0; $i<count($newarray); $i++){
for($j=1; $j<count($newarray2); $j++){
if($newarray2[$j]["id"]==$newarray[$i]["id"]){
$num++;
}

}
$cleanarray[$k] = [
'id' => $newarray[$i]["id"],
'date' => $newarray[$i]["date"],
'occurences' => $num
];
$k++;
$num=0;
}

Но многие элементы повторяются, с одними и теми же вхождениями, но несколько раз, и в других случаях повторяющиеся элементы (с одним и тем же идентификатором) будут иметь разные вхождения, поэтому я не знаю, что я могу сделать, я знаю, что есть функция из:

$occurences = array_count_values($array);

Но это не работает в этом случае, как я могу подойти к решению?

0

Решение

Вы можете сделать это, как показано ниже:

$final_array = array();

foreach($newarray as $arr){
if(!in_array($arr['id'],array_keys($final_array))){
$final_array[$arr['id']] = $arr;
$final_array[$arr['id']]['occurences'] = 1;
}else{
$final_array[$arr['id']]['occurences'] += 1;
}
}
$final_array= array_values($final_array);
print_r($final_array);

Выход:- https://eval.in/847242

Примечание: — если вы хотите, чтобы конечный массив был в порядке возрастания идентификатора, используйте usort () функция как ниже: —

function cmpId($a, $b) {
return ($a['id'] - $b['id']);
}

usort($final_array, "cmpId");
print_r($final_array);

Выход:- https://eval.in/847245

0

Другие решения

Я знаю, что вы ищете, но я думаю, что это может решить ваши проблемы:

$newarray[0] = [
'id' => '2',
'date' => '2016-04-22'
];
$newarray[1] = [
'id' => '2',
'date' => '2016-04-12'
];
$newarray[2] = [
'id' => '2',
'date' => '2016-04-12'
];
$newarray[3] = [
'id' => '1',
'date' => '2016-03-11'
];
$newarray[4] = [
'id' => '2',
'date' => '2016-03-05'
];
$newarray[5] = [
'id' => '1',
'date' => '2016-03-01'
];

foreach($newarray as $key => $value){
if(isset($found[$value['id']][$value['date']])) {
$found[$value['id']][$value['date']]++;
} else {
$found[$value['id']][$value['date']] = 1;
}
}
print_r($found);

это вернет что-то вроде:

Array
(
[2] => Array
(
[2016-04-22] => 1
[2016-04-12] => 2
[2016-03-05] => 1
)

[1] => Array
(
[2016-03-11] => 1
[2016-03-01] => 1
)

)
1

Использование временных ключей для этого процесса будет наиболее эффективным способом. Временные ключи упрощают задачу массива вывода, требуя меньше и быстрее проверки. Если вы хотите отсортировать id после того, как массив результатов сгенерирован, временные ключи позволяют ksort() вызов.

Код: (демонстрация)

$newarray=[
['id' => '2','date' => '2016-04-22'],
['id' => '2','date' => '2016-04-13'],
['id' => '2','date' => '2016-04-12'],
['id' => '1','date' => '2016-03-11'],
['id' => '2','date' => '2016-03-05'],
['id' => '1','date' => '2016-03-01']
];

foreach($newarray as $a){
if(!isset($result[$a['id']])){
$result[$a['id']]=array_merge($a,['occurrences'=>1]);  // use id as temp key, preserve first found date
}else{
++$result[$a['id']]['occurrences'];  // only update occurrences to preserve date
}
}
ksort($result);  // optionally sort on id ASC
var_export(array_values($result));  // remove temporary keys from first level and print to screen

Выход:

array (
0 =>
array (
'id' => '1',
'date' => '2016-03-11',
'occurrences' => 2,
),
1 =>
array (
'id' => '2',
'date' => '2016-04-22',
'occurrences' => 4,
),
)
1
По вопросам рекламы [email protected]