PHP遍历多维数组,统计里面的Strings,并根据count unset

PHP Iterate through multidimensional Array, count Strings inside and unset based on count

我想遍历一个多维数组,计算其中字符串的出现次数,并删除计数高于的数组项,例如3.

我已经在 N^N 循环中尝试了 array_search、array_count_values 和 strpos 的相当混乱的组合,但这需要很长时间才能处理并且结果是错误的.. .

这是数组,我正在尝试更改

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 次,我正在寻找一种删除项目的方法。

你们能帮我解决这个问题吗?

是的,我不得不处理类似的事情。如果您正在查看一个大约 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>';

我正在取消设置子数组中的那个项目,因为我不确定你是否想取消设置整个项目。

我要问你的第一个问题是 "where is your data coming from?" 如果这是来自数据库,那么我建议你在那里调整你的查询。您绝对可以在 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]);
        }
    }
}

我无法使用一刀切的方法,但为了将来参考,我将分享我的 "solution"。感觉不是特别复杂,但它完成了工作...

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;
    }