PHP перебирает многомерный массив, подсчитывает количество строк внутри и сбрасывает их в зависимости от количества

Я хочу перебрать многомерный массив, сосчитать вхождения строки внутри и удалить элементы массива, где количество больше, например, например. 3.

Я уже пробовал довольно грязную комбинацию array_search, array_count_values ​​и strpos в цикле N ^ N, но это занимает много времени, и результаты ошибочны …

Это Массив, я пытаюсь переделать

array(2) {
[0]=>
array(13) {
["id"]=>
string(6) "1234"["name"]=>
string(28) "aa"["productcategory"]=>
string(30) "Branch1^^subbranch1"["streamID"]=>
int(0)
["streamContext"]=>
string(16) "static"["prio"]=>
string(3) "100"}
[1]=>
array(11) {
["id"]=>
string(6) "9876"["name"]=>
string(30) "bb"["productcategory"]=>
string(66) "Branch1^^subbranch2"["streamID"]=>
int(0)
["streamContext"]=>
string(16) "static"["prio"]=>
string(3) "100"}
}

В окружающем массиве может быть около 200 предметов. Я ищу способ удаления товаров, если их товарная категория найдена более X раз.

Ребята, можете ли вы помочь мне с этим?

0

Решение

Да, мне приходилось иметь дело с чем-то похожим. Если вы смотрите на массив около 200, то создание цикла счетчика должно быть слишком медленным, а затем сбросить значения исходного массива на основе этих счетчиков. Я предоставил шаблон, чтобы подумать, чтобы увидеть, если вы в этом направлении.

Создает копию массива, затем считает productcategoryКонечно, я предполагаю, что category^^subcategory это количество, которое вы ищете.

<?php

$your_array = array(
array(
array(
"id" => "1234",
"name" => "aa",
"productcategory" => "Branch1^^subbranch1",
"streamID" => '',
"streamContext" => "static",
"prio" => "100",
),
array(
"id" => "9876",
"name" => "bb",
"productcategory" => "Branch1^^subbranch1",
"streamID" => '',
"streamContext" => "static",
"prio" => "100",
),
array(
"id" => "9876",
"name" => "bb",
"productcategory" => "Branch1^^subbranch3",
"streamID" => '',
"streamContext" => "static",
"prio" => "100",
),
array(
"id" => "9876",
"name" => "bb",
"productcategory" => "Branch1^^subbranch2",
"streamID" => '',
"streamContext" => "static",
"prio" => "100",
),
array(
"id" => "9876",
"name" => "bb",
"productcategory" => "Branch1^^subbranch3",
"streamID" => '',
"streamContext" => "static",
"prio" => "100",
),
array(
"id" => "9876",
"name" => "bb",
"productcategory" => "Branch1^^subbranch1",
"streamID" => '',
"streamContext" => "static",
"prio" => "100",
),
),
);




$counters = array();
$limit = 1; // whatever the limit is that you want
foreach ($your_array as $index => $array) {
for ($i = 0; $i < count($array); $i++) {
if (!isSet($counters[$array[$i]['productcategory']])) {
$counters[$array[$i]['productcategory']] = 0;
}
$counters[$array[$i]['productcategory']]++;
if ($counters[$array[$i]['productcategory']] > $limit) {
unset($your_array[$index][$i]);
}
}
}

print '<pre>' . print_r($counters, true) . '</pre>';
print '<pre>' . print_r($your_array, true) . '</pre>';

Я отменяю этот элемент в подмассиве, так как не уверен, что вы хотите просто сбросить весь элемент.

0

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

Мой первый вопрос к вам будет «откуда ваши данные?» Если это происходит из базы данных, то я бы порекомендовал вам настроить свой запрос там. Вы можете определенно решить эту проблему в PHP, но по мере роста вашего набора данных потребуется больше и больше времени для циклического перебора набора данных в PHP.

Чтобы решить эту проблему в PHP, я бы порекомендовал вам создать новый массив «product index». Этот массив будет ассоциироваться с именем продукта в качестве ключей, а значения будут содержать массив всех индексов верхнего уровня в массиве набора данных. После того, как вы построили индексный массив, вы можете зациклить его, чтобы найти, какие типы продуктов встречаются в основном наборе данных более 3 раз, и быстро удалить эти элементы.

$productIndex = [];

// Build an index of product categories
foreach($dataset as $i => $row) {
if (!is_array($productIndex[$row['productcategory']]) {
$productIndex[$row['productcategory']] = [];
}
$productIndex[$row['productcategory']][] = $i;
}

// Search for indexes with > 3 rows
foreach($productIndex as $items) {
if (count($items) > 3) {
// Delete said rows
foreach ($items as $index) {
unset($dataset[$index]);
}
}
}
0

Я не смог использовать подход «один размер подходит всем», но для дальнейшего использования я поделюсь своим «решением». Это не кажется супер сложным, но это делает работу …

function filter_categories($input, $count) {

$output = $input;

$exploded_input = [];
foreach ($output as $key => $value) {
$exploded_items = explode("^^", $value["productcategory"]);
array_push($exploded_input, $exploded_items);
}
$sortedbyCategory = [];

$last_items = [];
$counted_items = [];
foreach ($exploded_input as $key => $value) {
$end = end($value);
array_push($last_items, $end);
}

$counted = array_count_values($last_items);

foreach ($counted as $key => $value) {
if($value<=$count) {
unset($counted[$key]);
}
}
foreach ($counted as $k => $v) {
for ($i=0; $i < count($input); $i++) {
if(strpos($input[$i]["productcategory"], $k)){
if($counted[$k] > $count) {
$input[$i]["hide"] = true;
$counted[$k]--;
}

}

}
}
foreach ($input as $key => $value) {
if(isset($value["hide"])) {
unset($input[$key]);
}
}

return $input;
}
0