Сравнить и удалить некоторые подмассивы одного массива PHP

12
D
На сайте с 28.06.2008
Offline
1008
612

Есть массив с подмассивами вида:


[265]=>
object(stdClass)#284 (11) {
["id"]=>
string(6) "119720"
["category_id"]=>
string(2) "26"
["section_id"]=>
string(1) "5"
["year"]=>
string(1) "2018"
}
[266]=>
object(stdClass)#285 (11) {
["id"]=>
string(6) "514202"
["category_id"]=>
string(2) "26"
["section_id"]=>
string(1) "5"
["year"]=>
string(1) "0"
}
}

В этом многомерном массиве есть подмассивы с одинаковыми ["id"] но разными ["year"].

["year"] могут быть или 0 или 2018.

Мне нужно удалить дубли (подмассивы) с одинаковым ID и ["year"] = 0.

В этом многомерном массиве могут быть уникальные ["id"] с ["year"] = 0 - их удалять не нужно.

Удалить нужно только те подмассивы с ["year"] = 0 - для которых есть дубль с таким же ["id"] но ["year"] = 2018

Как это сделать?

edogs software
На сайте с 15.12.2005
Offline
743
#1

Банально в лоб же, никаких хитростей. Делаете пустой доп. массив.

Проходите по основному массиву, делаете проверку есть ли ИД фильма в доп. массиве и если есть, то какой у него там год.

Если там год 0, то удаляете старый объект и и заменяете данные в доп. массиве на текущие.

Если если год 2018, то удаляете текущий объект.

Если там не фига еще нет, просто заносите в доп. массив ИД и год и ИД объекта.

Разработка крупных и средних проектов. Можно с криптой. Разумные цены. Хорошее качество. Адекватный подход.
D
На сайте с 28.06.2008
Offline
1008
#2

Точно, спс!!!

S
На сайте с 30.09.2016
Offline
469
#3

Это не многомерный массив. И это важно.

Отпилю лишнее, прикручу нужное, выправлю кривое. Вытравлю вредителей.
D
На сайте с 28.06.2008
Offline
1008
#4

Потратил пару часов и вынужден признаться что где-то с моей логикой проблемы :(

//создал пустой массив
$arrayFinal = array ();

foreach ($value2 as $item){
array_push($arrayFinal, $item); //добавил первую запись
$i=0;
if ($arrayFinal[$i]->id == $item->id){ //начинаю проверять ID в новом массиве и в старом
if ($arrayFinal[$i]->year < $item->year){ // если они одинаковые - проверяю год
unset($arrayFinal[$i]); //если в новом год меньше, т.е. ноль (там два варианта только возможно), то удаляю подмассив из нового
array_push($arrayFinal, $item); /// и вставляю с большим годом из старого
}
}
$i++;
var_dump($arrayFinal);

}

И в итоге этого говнокода получаю очень длинный цикл, сразу его прерываю ибо понимаю что где-то накосячил....

Samail
На сайте с 10.05.2007
Offline
336
#5
Dram:
получаю очень длинный цикл

Может это не цикл длинный, а браузер виснет когда пытается отобразить при каждой итерации var_dump($arrayFinal); который ты внутрь цикла вставил. А с логикой да, проблемы, ты получается добавляешь текущий $item в массив и тут-же его с самим собой и сравниваешь.

IL
На сайте с 20.04.2007
Offline
418
#6
Dram:
В этом многомерном массиве есть подмассивы с одинаковыми ["id"] но разными ["year"].

Если не ошибаюсь, всё это получается из базы..

а) можно отфильтровать на уровне базы.

б) можно отсортировать по ID и year DESC

(555222, 2018), (555223, 2018), (555223, 0), (555224, 2018),(555224, 0)

и в цикле:


$newItems= [];
foreach ($bigmassive as $item) {
isset($newItems[$item->id]) or $newItems[$item->id] = $item;
}
... :) Облачные серверы от RegRu - промокод 3F85-3D10-806D-7224 ( http://levik.info/regru )
D
На сайте с 28.06.2008
Offline
1008
#7

Я в консоле смотрю не в браузере.

Я хотел сделать так.

1. Создать пустой массив.

2. Начать добавлять в него по одной записи из главного массива.

3. Начиная со второй итерации я хотел сравнивать значения ID из основного (старого массива) со всеми уже добавленными ID в новом массиве.

4. Если есть совпадения по ID - проверяем значение года.

5. Если в новом массиве значение года - 0, а в старом с таким же ID значение больше 0 - то заменяем массив на тот где год больше.

Вот вроде и все

---------- Добавлено 13.09.2019 в 08:57 ----------

ivan-lev, да получаю из базы запросом, но результат мне нужен в формате

ORDER BY `t3`.`value` DESC
IL
На сайте с 20.04.2007
Offline
418
#8
Dram:
ivan-lev, да получаю из базы запросом, но результат мне нужен в формате

У меня вообще большие сомнения, что он Вам именно в таком формате нужен.. =)


$newItems= [];
foreach ($bigmassive as $item) {
(isset($newItems[$item->id]) && $newItems[$item->id]->year > $item->year)
or $newItems[$item->id] = $item;
}
D
На сайте с 28.06.2008
Offline
1008
#9

ivan-lev, АЙ ДА ШАМАН - все отработало как нужно спс, попытаюсь теперь понять как оно работает :))) Спасибо!

D
На сайте с 28.06.2008
Offline
1008
#10

Блин, все равно где-то ошибка. Вот я упростил выборку до одной фирмы чтобы легче было понять

На выходе запросы имеем массив:

array(9) {
[0]=>
object(stdClass)#19 (3) {
["id"]=>
string(4) "1822"
["value"]=>
string(4) "814"
["year"]=>
string(4) "2017"
}
[1]=>
object(stdClass)#20 (3) {
["id"]=>
string(4) "1822"
["value"]=>
string(2) "870"
["year"]=>
string(4) "2015"
}
[2]=>
object(stdClass)#21 (3) {
["id"]=>
string(4) "1822"
["value"]=>
string(4) "855"
["year"]=>
string(4) "2012"
}
[3]=>
object(stdClass)#22 (3) {
["id"]=>
string(4) "1822"
["value"]=>
string(4) "802"
["year"]=>
string(4) "2019"
}
[4]=>
object(stdClass)#23 (3) {
["id"]=>
string(4) "1822"
["value"]=>
string(2) "699"
["year"]=>
string(4) "2016"
}
[5]=>
object(stdClass)#24 (3) {
["id"]=>
string(4) "1822"
["value"]=>
string(5) "958"
["year"]=>
string(4) "2011"
}
[6]=>
object(stdClass)#25 (3) {
["id"]=>
string(4) "1822"
["value"]=>
string(4) "814"
["year"]=>
string(4) "2014"
}
[7]=>
object(stdClass)#26 (3) {
["id"]=>
string(4) "1822"
["value"]=>
string(4) "775"
["year"]=>
string(4) "2010"
}
[8]=>
object(stdClass)#27 (3) {
["id"]=>
string(4) "1822"
["value"]=>
string(5) "750"
["year"]=>
string(4) "2018"
}
}

Как мы видим, айди одной и той же фирмы, меняются только года и значения. Далее я использую следующий код:

foreach ($result as $key => $value){
if ($value->year !== '2018'){ // тут если не нужный мне год присваиваю году и валю нули
$value->year = '0';
$value->value = '0';
// unset($result[$key]);
}
$value2[] = $value;
}

//// это код ivan-lev собираем новый массив с уникальными ID без повторов.
$newItems= [];
foreach ($value2 as $item) {
(isset($newItems[$item->id]) || $newItems[$item->id]->year > $item->year)
or $newItems[$item->id] = $item;
}
var_dump($newItems);

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

PHP Notice: Undefined offset: 1822 in /var/www/rate.php on line 37

Notice: Undefined offset: 1822 in /var/www/rate.php on line 37
PHP Notice: Trying to get property 'year' of non-object in /var/www/rate.php on line 37

Notice: Trying to get property 'year' of non-object in /var/www/rate.php on line 37
array(1) {
[1822]=>
object(stdClass)#19 (3) {
["id"]=>
string(4) "1822"
["value"]=>
string(1) "0"
["year"]=>
string(1) "0"
}
}

А по идее должен был получить это

{
["id"]=>
string(4) "1822"
["value"]=>
string(5) "750"
["year"]=>
string(4) "2018"
}

В чем ошибка?

P.S. (нотисы выше ругаются на строку - (isset($newItems[$item->id]) || $newItems[$item->id]->year > $item->year))

---------- Добавлено 13.09.2019 в 14:20 ----------

Так одну проблему решил

Надо было так

($newItems[$item->id]->year > $item->year)

Теперь получаю массив фирм с ценами за нужных год, но они не отсортированы по убыванию

Изначально в

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

массив $result пришел отсортированный ORDER BY `t3`.`value` DESC

но где то потом сортировка сбилась...

где она могла слететь или по другому - как опять массив по value сортирнуть?

---------- Добавлено 13.09.2019 в 14:30 ----------

проблему окончательно решил так

function cmp_function_desc($a, $b){
return ($a->value < $b->value);
}
uasort($items, 'cmp_function_desc');
12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий