从PHP中的多维数组中删除重复数组

时间:2019-04-14 18:42:19

标签: php arrays multidimensional-array duplicates

如何从这个数组中过滤重复的值?

实际上,对于相同的countrycity,数据是相同的-除了人口发生了变化。

如何删除包含更高人口的阵列?

$arr = array
(
    "100" => array(
        array(
            "country" => 'France',
            "city" => 'Paris',
            "population" => '1800000',
        ),
        array(
            "country" => 'France',
            "city" => 'Paris',
            "population" => '2000000',
        ),
        array(
            "country" => 'France',
            "city" => 'Toulouse',
            "population" => '500000',
        ),
    )
    "101" => array(
        array(
            "country" => 'Russia',
            "city" => 'Moscow',
            "population" => '144000000',
        )
    )
);

因此,所需的输出应为:

$arr = array
(
    "100" => array(
        array(
            "country" => 'France',
            "city" => 'Paris',
            "population" => '1800000'
        ),
        array(
            "country" => 'France',
            "city" => 'Toulouse',
            "population" => '500000'
        ),
    )
    "101" => array(
        array(
            "country" => 'Russia',
            "city" => 'Moscow',
            "population" => '144000000',
        )
    )
);

这是我尝试过的

$temp_array = [];
foreach ($array as &$v) {
    if (!isset($temp_array[$v['country']] && $temp_array[$v['city']]))
        $temp_array[$v[$key]] =& $v;
    }
$array = array_values($temp_array);
return $array;

4 个答案:

答案 0 :(得分:3)

您可以首先使用array_reduce过滤较低的人口(使用国家和城市的组合作为关键字)。然后将它们炸开并使用该最小值重置数组:

foreach($arr as $k => &$ar) {
    $temp = array_reduce($ar, function ($carry, $item) {
        $key = $item["country"] . "###" . $item["city"];
        $carry[$key] = (isset($carry[$key]) && $item["population"] > $carry[$key]) ?  $carry[$key] : $item["population"];
        return $carry;
    }, []);
    $ar = [];
    foreach($temp as $k => $val) {
        list($country, $city) = explode("###", $k);
        $ar[] = array("country" => $country, "city" => $city, "population" => $val);
    }
}

实时示例:3lv4

修改

您可以使用array_filter而不是foreach循环来避免应付问题:

$ar = array_filter($ar, function ($item) use ($mins) {
    $key = $item["country"] . "###" . $item["city"];
    return $mins[$key] == $item["population"];
 });

答案 1 :(得分:1)

您可以使用国家和城市创建复合数组键,从而轻松跟踪循环播放的内容。
由于city可能不在数组中,因此如果不需要通知就可以使用a。

foreach($arr as $key => $sub){
    foreach($sub as $item){
        if(isset($item['city'])){
            if(!isset($res[$key][$item['country'] . $item['city']])) $res[$key][$item['country'] . $item['city']] = $item;
            if($res[$key][$item['country'] . $item['city']] < $item['population']) $res[$key][$item['country'] . $item['city']] = $item;
        }else{
            if(!isset($res[$key][$item['country']])) $res[$key][$item['country']] = $item;
            if($res[$key][$item['country']] < $item['population']) $res[$key][$item['country']] = $item;
        }
    }
}
var_dump($res);

输出:

array(2) {
  [100]=>
  array(2) {
    ["FranceParis"]=>
    array(3) {
      ["country"]=>
      string(6) "France"
      ["city"]=>
      string(5) "Paris"
      ["population"]=>
      string(7) "1800000"
    }
    ["FranceToulouse"]=>
    array(3) {
      ["country"]=>
      string(6) "France"
      ["city"]=>
      string(8) "Toulouse"
      ["population"]=>
      string(6) "500000"
    }
  }
  [101]=>
  array(1) {
    ["Russia"]=>
    array(2) {
      ["country"]=>
      string(6) "Russia"
      ["population"]=>
      string(9) "144000000"
    }
  }
}

https://3v4l.org/KNuId

如果您需要删除“ FranceToulouse”之类的键,则只需再次循环数组并使用array_values

答案 2 :(得分:0)

从外观上看,

该数组已按国家/地区分组,我假设每个数组元素只有来自同一国家/地区的子数组。我还要说的是,为每个国家/地区建立一个包含键的数组是更明智的选择,以便于访问和过滤,所以我会说

$populations = [];

foreach($array as $arr) {
if(!isset($populations[$arr['country']])) $populations[$arr['country']] = [];//create an array entry for the country
     $cities = [];
     foreach($arr as $city) {
       if(!isset($cities[$city]) || $cities[$city]['population'] > $city['population']) $cities[$city] = ['population' => $city['population']];//you could put the value straight in, but this means if you expand later you could add extra fields to each cities info such as district, number of unemployed or whatever you're using this for

     }
$populations[$arr['country']] = $cities;
}

这与您所概述的输出略有不同,但是我认为它将使进一步使用变得更简单,因为您可以访问特定国家/地区的所有数据,然后访问城市中的所有数据,而不必不断循环浏览。并检查孩子是否包含您所追求的国家/地区。

我希望这是有道理的,我的未婚妻正在尝试与我同时回答有关宜家的问题,因此它可能不是100%完美,但至少会为您指明一个正确的方向

答案 3 :(得分:0)

我做了两个嵌套循环,第一个嵌套子数组包含一个特定键(例如100和101)的所有内容。

接下来,我遍历数据,并保留一个包含两个级别的临时数组,第一个级别将国家作为关键,第二个级别将城市作为跟踪最低人口的关键。

完成上述操作后,我遍历临时数组以正确的格式获取国家,城市和人口,并将其附加到新数组中。然后,我将以前的数组替换为这个新获取的结果。

<?php

$arr = array
(
    "100" => array(
        array(
            "country" => 'France',
            "city" => 'Paris',
            "population" => '1800000',
        ),
        array(
            "country" => 'France',
            "city" => 'Paris',
            "population" => '2000000',
        ),
        array(
            "country" => 'France',
            "city" => 'Toulouse',
            "population" => '500000',
        ),
    ),
    "101" => array(
        array(
            "country" => 'Russia',
            "city" => 'Moscow',
            "population" => '144000000',
        )
    )
);

foreach($arr as $key=>$subarr) {
    $tmp = array();
    foreach($subarr as $v) {
        $country = $v['country'];
        $city = $v['city'];
        $population = $v['population'];

        if(isset($tmp[$country])) {
            if(isset($tmp[$country][$city])) {
                if($tmp[$country][$city] > $population) {
                    $tmp[$country][$city] = $population;
                }
            } else {
                $tmp[$country][$city] = $population;
            }
        } else {
            $tmp[$country] = array();
            $tmp[$country][$city] = $population;
        }
    }

    $res = array();
        foreach($tmp as $country=>$cities) {
            foreach($cities as $city=>$population) {
                $res[] = array('country'=>$country,'city'=>$city,'population'=>$population);
            }
        }
    $arr[$key] = $res;

}
print_r($arr);