【问题标题】:How to associate and filter two related arrays?如何关联和过滤两个相关数组?
【发布时间】:2020-09-19 18:46:18
【问题描述】:

我有两个数组,我想在处理它们时链接在一起。

$dat = array(
    "2020-02-01", 
    "2020-02-05",
    "2020-02-10",
    "2020-02-12",
    "2020-02-15"
);
$word = array(
    "Attend To,Explore,Unaided,dull,bad"
); 

//User input
$start = "2020-01-01";
$end = "2020-02-07";

我希望输入也影响第二个数组,所以当第一个数组从第一个 2 获得结果时,第二个数组也应该从第一个 2 获得结果。

//Filter out dates between start and end date
$result = array_filter($dat, function($data_item) use($start, $end) {
    return $data_item >= $start && $data_item <= $end;
});

结果是

Array
(
    [0] => 2020-02-01
    [1] => 2020-02-05
)

我希望它能够链接 $dat$word 以便 word 的结果也是

Array
(
    [0] => Attend To
    [1] => Explore
)

【问题讨论】:

    标签: php arrays filtering relational associative


    【解决方案1】:

    对于这种情况,我认为函数式编程的可读性/吸引力不大。只需使用一个简单的 foreach 循环并有条件地抓取与共享索引相关的单词。

    由于这两个数组共享共同的索引,combine 这两个数组不需要做任何工作——只需引用索引即可。

    代码:(Demo)

    $dat = ["2020-02-01", "2020-02-05", "2020-02-10", "20-02-12", "2020-02-15"];
    $word = ["Attend To,Explore,Unaided,dull,bad"];
    $words = explode(',', $word[0]);
    
    //User input
    $start = "2020-01-01";
    $end = "2020-02-07";
    
    $result = [];
    foreach ($dat as $index => $date) {
        if ($date >= $start && $date <= $end) {
            $result[] = $words[$index];
        }
    }
    var_export($result);
    

    输出:

    array (
      0 => 'Attend To',
      1 => 'Explore',
    )
    

    【讨论】:

    • 应该注意,除了它更具可读性之外,它也可能是迄今为止性能最高的答案。它摆脱了函数开销和传递参数,并避免了对数组的额外操作。
    【解决方案2】:

    array_filter之后会保留原来的key,所以通过计算交集来获取相同key的entry。看来$word 是一个带有字符串的单元素数组,所以只需将其分解:

    $word_result = array_intersect_key(explode(',', $word[0]), $result);
    

    查看Demo

    如果其中一个数组具有唯一值,您可以组合该数组并对其进行操作。

    $comb = array_combine(explode(',', $word[0]), $dat);
    
    $result = array_filter($comb, function($data_item) use($start,$end) {
        return $data_item >= $start && $data_item <= $end;
    });
    

    这会产生:

    Array
    (
        [Attend To] => 2020-02-01
        [Explore] => 2020-02-05
    )
    

    您可以按原样使用数组,也可以使用array_keys 将键作为$word 数组。

    如果不能保证是$word[0],那么您可以使用reset($word)current($word)

    【讨论】:

    • 第二个数组只有一个字符串,它是如何工作的?
    • 我没有发现它是 1 个字符串,看起来像一个数组。添加了explode
    • 又加了一个,可能会派上用场。
    【解决方案3】:

    假设数组具有相同的键(我对其进行了更改以反映这一点),一个可能的解决方案是使用常量ARRAY_FILTER_USE_BOTHarray_filter,以便该键在回调函数中可用。

    在这里,我在过滤数据时用单词填充第二个数组$result2(注意在use$result2 中添加的东西是通过引用传递的):

    $dat = array("2020-02-01","2020-02-05","2020-02-10","20-02-12","2020-02-15");
    $word = array("Attend To","Explore","Unaided","dull","bad"); 
    
    //User input
    $start = "2020-01-01";
    $end = "2020-02-07";
    
    //Filter out dates between start and end date
    $result2 = [];
    $result = array_filter($dat, function($data_item, $key) use($start, $end, $word, &$result2) {
        if($data_item >= $start && $data_item <= $end){
            $result2[$key] = $word[$key];
            return true;
        }
        return false;
    }, ARRAY_FILTER_USE_BOTH);
    

    AbraCadaver 的答案非常适合只需要过滤的情况,但如果有人必须在过滤回调中执行额外操作,这可能很有用..

    【讨论】:

      猜你喜欢
      • 2015-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-15
      • 1970-01-01
      相关资源
      最近更新 更多