如何从数组中过滤值,然后按自定义顺序对它们进行排序?

时间:2017-08-20 04:12:58

标签: php arrays sorting filtering

我正在解析一个JSON文件,我根据某个键过滤掉了我想要的值,然后遍历它,为我想要的其他键值创建变量。现在,我已将它排序,我不知道如何订购它,所以它按我想要的顺序显示。是否有一种简化的方法来过滤和订购一个快速功能,或者我是否需要单独订购,如果是这样,最佳方法是什么?

以下是代码中的代码片段,用于在循环之前根据“event”键过滤数组。此外,下面的顺序是我希望它们在输出时显示的顺序。

$str = file_get_contents($url); // put the contents of the file into a variable
$o=json_decode($str,true);
$features=$o['features'];

// Lets filter the response to get only the values we want
$filtered = array_filter($features,function($el){
    $alerts = array('Tornado Warning', 'Severe Thunderstorm Warning', 'Hurricane Warning', 'Tropical Storm Warning', 'Flash Flood Warning', 'Flood Warning', 'Tornado Watch', 'Severe Thunderstorm Watch', 'Hurricane Watch', 'Tropical Storm Watch', 'Flash Flood Watch');

    return in_array($el['properties']['event'],$alerts);
});

3 个答案:

答案 0 :(得分:3)

使用array_filter()array_flip()usort()

$alerts = array(
    'Tornado Warning', 
    'Severe Thunderstorm Warning', 
    'Hurricane Warning', 
    'Tropical Storm Warning', 
    'Flash Flood Warning', 
    'Flood Warning', 
    'Tornado Watch', 
    'Severe Thunderstorm Watch', 
    'Hurricane Watch', 
    'Tropical Storm Watch', 
    'Flash Flood Watch',
);

// filter features, remove those which are not of any of the desired event types 
$alertFeatures = array_filter($features, function(array $feature) use ($alerts) {
    $eventType = $feature['properties']['event'];

    return in_array($eventType, $alerts);
});

// flip alerts, mapping names of alerts to index in array (we'll use it to order)
$order = array_flip($alerts);

// sort elements by order of event type as desired
usort($alertFeatures, function (array $a, array $b) use ($order) {
    $eventTypeA = $a['properties']['event'];
    $eventTypeB = $b['properties']['event'];

    return $order[$eventTypeA] - $order[$eventTypeB];
});

var_dump($alertFeatures);

供参考,见:

答案 1 :(得分:0)

可能不是最有效的解决方案,但您可以对阵列进行嵌套迭代,并以正确的顺序复制相关功能。

function filterAndSort($features, $alerts){
    $output = array();

    $features_count = count($features);
    $alerts_count = count($alerts);

    for($i=0;$i<$alerts_count;$i++){
        for($u=0;$u<$features_count;$u++){
            if($alerts[$i]==$features[$u]['properties']['event'])
                $output[] = $features[$u];
        }
    }

    return $output;
}

编辑:我能想到的另一种方法是为每种类型创建一个临时数组,然后将所有这些数组连接在一起。但我怀疑这会有什么显着的性能提升。它肯定会花费更多的RAM。

function filterAndSort($features, $alerts){
    $output = array();
    $groups = array();

    $features_count = count($features);
    $alerts_count = count($alerts);

    for($i=0;$i<$alerts_count;$i++){ // create empty arrays for each alert type
        $groups[$i] = array();
    }

    for($u=0;$u<$features_count;$u++){
        $index = array_search($features[$u]['properties']['event'],$alerts); // get index of alert type
        if($index!==false) // if feature has one of the relevant alert types
            $groups[$index][] = $features[$u]; // push the the feature into the designated array
    }

    for($i=0;$i<$alerts_count;$i++){
        $group_count = count($groups[$i]);
        for($u=0;$u<$group_count;$u++){
            $output[] = $groups[$i][$u]; // copy each element into the output in the right order
        }
    }

    return $output;
}

答案 2 :(得分:0)

您可以像这样简单地重新创建数组:

function selectByKey($keys,$array){
  $prepare = array();
  foreach($keys as $key){
    $prepare[$key] = $array[$key];
  }
  return $prepare;
}

并像这样使用它:

$all_items = array(
  'item1' => 'Item 1',
  'item2' => 'Item 2',
  'item3' => 'Item 3',
  'item4' => 'Item 4'
);
$selected_items = selectByKey(array(
  "item4",
  "item2"
),$all_items);

您不仅可以选择(和过滤)自定义数组项,还可以按照所需的方式对其进行排序,并在需要时使用数组项几次。