【问题标题】:split arrays by date and other identifier按日期和其他标识符拆分数组
【发布时间】:2022-01-18 11:13:56
【问题描述】:

我有从 mongodb 到数组的数据,我想处理返回数据以按日期和其他值拆分它,这是我目前得到的结果,我需要一些帮助

<?php

$stats=array(
    array("source"=>501,"status"=>"answered","dest"=>"100","date"=>"2022-17-01"),
    array("source"=>501,"status"=>"noAnswer","dest"=>"120","date"=>"2022-17-01"),
    array("source"=>501,"status"=>"answered","dest"=>"100","date"=>"2022-18-01"),
    array("source"=>502,"status"=>"answered","dest"=>"120","date"=>"2022-17-01"),
    array("source"=>502,"status"=>"answered","dest"=>"130","date"=>"2022-17-01"),
    array("source"=>502,"status"=>"answered","dest"=>"110","date"=>"2022-18-01")
);

$new1 = array();
$answer = 0;
$noanswer = 0;
$lastsrc = '';
$lastdate = '';
$dest=0;
foreach ($stats as $new) {

    $src = $new['source'];
    $date = $new['date'];
 
    if ( $lastsrc == $src && $lastdate == $date ) {
        $dest++;

        if($new['status'] == 'answered'){ $answer++; }
        if($new['status'] == 'noanswer'){ $noanswer++;}

        $new1[] = array('source' => $src, 
                        'date' => $date, 
                        'ans' => $answer, 
                        'nonans' => $noanswer, 
                        'dest' => $dest  );
    } else if ( $lastsrc == $src && $lastdate != $date ) {

        $dest++;

        if($new['status'] == 'answered'){ $answer++;}
        if($new['status'] == 'noanswer'){ $noanswer++;}

        $new1[] = array('source' => $src, 
                        'date' => $date, 
                        'ans' => $answer, 
                        'nonans' => $noanswer, 
                        'dest' => $dest  );
    } else {

        $dest++;

        if($new['status'] == 'answered'){ $answer++; }
        if($new['status'] == 'noanswer'){ $noanswer++;}
       
        $new1[] = array('source' => $src, 
                       'date' => $date, 
                       'ans' => $answer,
                       'nonans' => $noanswer, 
                       'dest' => $dest  );
        $lastsrc = $src;
        $lastdate = $date;
    }
}   
print_r($new1);
?>

我试图实现的是按日期和源拆分数据,所以如果在 foreach 循环中我找到相同的源和相同的日期,那么我修改数组而不是创建新数组,如果相反则创建新的数组

我试图得到的结果是:

    array("source"=>501,"ans"=>"1","noans" => 0,"dest"=>1,"date"=>"2022-17-01"),
    array("source"=>501,"ans"=>"1","noAnswer" => 1,"dest"=>2,"date"=>"2022-18-01"),
    array("source"=>502,"ans"=>"2","noans" => 0,"dest"=>2,"date"=>"2022-17-01"),
    array("source"=>502,"ans"=>"1","noans" => 0,"dest"=>1,"date"=>"2022-18-01")

我不确定它是否正确,任何帮助将不胜感激,谢谢

【问题讨论】:

  • 错字/拼写错误! if($new['status'] == 'asnwered')
  • 不知道dest 应该是什么,但在你的这部分逻辑中,你似乎将它增加了两次} else if ( $lastsrc == $src &amp;&amp; $lastdate != $date ) { 是吗??
  • 我修复了拼写,我正在寻找的结果是创建一个新数组,但拆分为源和日期,并计算 dest 的数量,回答者和未回答者,所以我得到每个来源每个日期并计算结果类似于问题中的示例,再次感谢 RiggsFolly
  • dest 是目的地 :)
  • 您如何在输出中获得"noAnswer",没有任何代码将其放入$new1

标签: php arrays


【解决方案1】:
<?php

$stats = [
    [ 'source' => 501, 'status' => 'answered', 'dest' => '100', 'date' => '2022-17-01' ],
    [ 'source' => 501, 'status' => 'noAnswer', 'dest' => '120', 'date' => '2022-17-01' ],
    [ 'source' => 501, 'status' => 'answered', 'dest' => '100', 'date' => '2022-18-01' ],
    [ 'source' => 502, 'status' => 'answered', 'dest' => '120', 'date' => '2022-17-01' ],
    [ 'source' => 502, 'status' => 'answered', 'dest' => '130', 'date' => '2022-17-01' ],
    [ 'source' => 502, 'status' => 'answered', 'dest' => '110', 'date' => '2022-18-01' ]
];

$result = [];

foreach ($stats as $stat) {
  $source = $stat['source'];
  $date = $stat['date'];
  $closure = static fn($item) => $item['source'] === $source && $item['date'] === $date;
  $found = array_filter($result, $closure);
  if (count($found) === 0) {
    $list = array_filter($stats, $closure);
    $list = array_map(static fn($item) => [ 'status' => $item['status'], 'dest' => $item['dest'] ], $list);
    $result[] = [
        'source' => $source,
        'date' => $date,
        'answered' => count(array_filter(array_column($list, 'status'), static fn($item) => $item === 'answered')),
        'noAnswer' => count(array_filter(array_column($list, 'status'), static fn($item) => $item === 'noAnswer')),
        'dest' => count(array_column($list, 'dest')),
    ];
  }
}

print_r($result);

【讨论】:

  • 这正是我所需要的 :) 谢谢 Lukas.j
【解决方案2】:

从要排序的字段创建复合键并使用关联数组。 (数组中的单个级别使排序/合并以及之后提取值(array_values())变得容易)然后您只需遍历$stats$result 一次。

$result = [];
foreach($stats as $stat) {
    $key = $stat['source'].'_'.$stat['date'];
    if (!array_key_exists($key, $result)) {
        $result[$key] = ['answered' => 0, 'noAnswer' => 0] + $stat;
    }

    $result[$key][$stat['status']]++;
    $result[$key]['dest'][$stat['dest']] = 1;
}
$result = array_map( // Transform "destinations key store" to count
    function($item) { 
        $item['dest'] = count($item['dest']); return $item; 
    },
    $result
);

print_r(array_values($result));
['source' => 501, 'status' => answered, 'dest' => 2, 'date' => 2022-17-01, 'answered' => 1, 'noAnswer' => 1],
['source' => 501, 'status' => answered, 'dest' => 1, 'date' => 2022-18-01, 'answered' => 1, 'noAnswer' => 0],
['source' => 502, 'status' => answered, 'dest' => 2, 'date' => 2022-17-01, 'answered' => 2, 'noAnswer' => 0],
['source' => 502, 'status' => answered, 'dest' => 1, 'date' => 2022-18-01, 'answered' => 1, 'noAnswer' => 0]

【讨论】:

    猜你喜欢
    • 2018-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多