PHP迭代通过多维数组,计算内部字符串并根据计数取消设置

时间:2015-12-09 14:12:04

标签: php arrays multidimensional-array foreach array-unset

我想迭代多维数组,计算内部String的出现次数并删除计数高于例如的数组项。 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次,我正在寻找一种方法来删除项目。

你们能帮助我吗?

3 个答案:

答案 0 :(得分: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>';

我在子数组中取消了这个项目,因为我不确定你是否想要取消整个项目。

答案 1 :(得分:0)

我的第一个问题是“你的数据来自哪里?”如果这是来自数据库,那么我建议你在那里调整你的查询。你绝对可以在PHP中解决这个问题,但随着数据集的增长,在PHP中循环数据集需要更长的时间。

要在PHP中解决这个问题,我建议您创建一个新的“产品索引”数组。此数组将与产品名称关联作为键,值将包含数据集数组中所有顶级索引的数组。一旦构建了索引数组,就可以循环使用它来查找主数据集中出现的次数超过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]);
        }
    }
}

答案 2 :(得分:0)

我还没有能够使用一种尺寸适合所有方法,但为了将来的参考,我将分享我的&#34;解决方案&#34;。它不像超级复杂,但它完成了工作......

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