【问题标题】:Getting multiple specific key value pairs if exist in associate array如果关联数组中存在多个特定键值对
【发布时间】:2021-05-09 19:30:56
【问题描述】:

我想根据某些条件将我的关联数组转换为数组:

  • 它应该包含多个列(因此,在这种情况下,不能使用array_column。)
  • 应该添加重复的日期
  • 如果为 NULL,它应该删除特定的子数组。 (array_filter)

输入:

array (
  0 => 
  array (
    'date' => "2019-03-31",
    'a' => '1',
    'b' => '1',
  ),
  1 => 
  array (
    'date' => "2019-04-02",   // If "SAME" date then ADD them
    'a' => '1',
    'b' => '1',
  ),
  2 => 
  array (
    'date' => "2019-04-02",   // If "SAME" date then ADD them
    'a' => '2',
    'b' => '1',
  ),
  3 => 
  array (
    'date' => "2019-04-10",
    'a' => '',                // If "NULL" then remove the particular sub-array
    'b' => '1',               
  ),
  4 => 
  array (
    'date' => "2019-04-18",
    'a' => '4',
    'b' => '10',
  ),
)


我尝试了以下方法,

虽然我能够在数组中选择多个列,但这给了我:

  • “重复”日期。
  • 包括具有“Null”值的子数组。
function colsFromArray(array $array, $keys)
{
    if (!is_array($keys)) $keys = [$keys];
    return array_map(function ($el) use ($keys) {
        $o = [];
        foreach($keys as $key){
            $o[$key] = isset($el[$key])?$el[$key]:false;
        }
        return $o;
    }, $array);
}


$result =  colsFromArray($arr, array("date", "a"));


所需输出:

array (
  0 => 
  array (
    'date' => "2019-03-31",
    'a' => '1',
  ),
  1 => 
  array (
    'date' => "2019-04-02",
    'a' => '3',
  ),
  2 => 
  array (
    'date' => "2019-04-18",
    'a' => '4',
  ),
)

【问题讨论】:

    标签: php arrays loops


    【解决方案1】:

    你可以试试这样的:

    function colsFromArray(array $array, $keys)
    {
        if (!is_array($keys)) $keys = [$keys];
    
        $returnArray = [];
    
        foreach($array as $in){
            foreach($keys as $key){
    
                //Check if the key already has a value
                if(isset($returnArray[$in['date']][$key]) && is_numeric($returnArray[$in['date']][$key])){
                    $returnArray[$in['date']][$key] += $in[$key];
                }
                //If the key is empty, continue
                elseif(empty($in[$key])){
                    continue;
                }
                //If value is to be set, set date as well
                else{
                    $returnArray[$in['date']]['date'] = $in['date'];
                    $returnArray[$in['date']][$key] = $in[$key];
                }
            }
        }
    
        //Return array after resetting indexes and removing empty entries
        return array_values(array_filter($returnArray));
    }
    

    【讨论】:

      【解决方案2】:

      您将列数组传递给客户函数的方式对于应该使用什么分组以及应该求和什么是模棱两可的。或者,如果您的第二个参数中的元素永远不会超过两个,那么您的自定义函数就缺乏灵活性。

      请注意@SverokAdmin 的答案如何在逻辑中硬编码date,但不能保证此列名将始终存在于第一个参数$array 中。因此,效用函数不能可靠地用作效用函数。

      考虑这个自定义函数,它提供您想要的结果,但允许更有意义的参数声明。我的 sn-p 允许您按一列或多列分组,在子数组中保留一列或多列,并指定应对哪一列求和。我不能使最后一列可迭代,因为您声明如果一列缺少值,则应从结果中省略它。换句话说,如果您想对ab 求和,那么您想要的结果是未知的,但是a 值之一是空的。

      代码:(Demo)

      function colsFromArray(array $array, $groupBy, $keepables, $summable): array
      {
          $groupBy = (array)$groupBy;
          $keepables = (array)$keepables;
          // cannot make $summable iterable type because question is unclear on the desired outcome when one of the columns is empty
      
          return array_values(
              array_reduce(
                  $array,
                  function ($result, $row) use($groupBy, $keepables, $summable) {
                      $uniqueKey = [];
                      foreach ($groupBy as $col) {
                          $uniqueKey[] = $row[$col];
                      }
                      $uniqueKey = implode('_', $uniqueKey);
                      
                      if (!$row[$summable]) {
                          return $result;
                      }
                      
                      foreach ($keepables as $keepable) {
                          $result[$uniqueKey][$keepable] = $row[$keepable];
                      }
                      $result[$uniqueKey][$summable] = ($result[$uniqueKey][$summable] ?? 0) + $row[$summable];
                      return $result;
                  },
                  []
              )
          );
      }
      
      var_export(
          colsFromArray($arr, 'date', 'date', 'a')
      );
      

      输出:

      array (
        0 => 
        array (
          'date' => '2019-03-31',
          'a' => 1,
        ),
        1 => 
        array (
          'date' => '2019-04-02',
          'a' => 3,
        ),
        2 => 
        array (
          'date' => '2019-04-18',
          'a' => 4,
        ),
      )
      

      【讨论】:

        猜你喜欢
        • 2017-09-01
        • 2022-01-07
        • 1970-01-01
        • 2013-07-08
        • 1970-01-01
        • 2018-08-31
        • 2020-03-23
        • 2017-02-07
        • 1970-01-01
        相关资源
        最近更新 更多