【问题标题】:Group array values based on key in php? [duplicate]根据php中的键对数组值进行分组?
【发布时间】:2012-12-16 07:13:33
【问题描述】:

我有一个这样的数组:

$str=
   Array
(
    [No] => 101
    [Paper_id] => WE3P-1
    [Title] => "a1"
    [Author] => ABC
    [Aff_list] => "University of South Florida, Tampa, United States"
    [Abstracts] => "SLA"

)

Array
(
    [No] => 101
    [Paper_id] => WE3P-1
    [Title] => "a2"
    [Author] => DEF
    [Aff_list] => "University of South Florida, Tampa, United States"
    [Abstracts] => "SLA "

)

Array
(
    [No] => 104
    [Paper_id] => TU5A-3
    [Title] => "a3"
    [Author] => GHI
    [Aff_list] => "University of Alcala, Alcala de Henares, Spain"
    [Abstracts] => "Microwave"

)

我想根据“否”作为主键对数组中的元素进行分组。输出应如下所示:

 array(6) {
  ["No"]=>
  string(6) "101"
  ["Paper_id"]=>
  string(6) "WE3P-1"
  ["Title"]=>
  string(80) ""a-1"
  ["Author"]=>
  string(14) "ABC"
  ["Aff_list"]=>
  string(51) ""University of South Florida, Tampa, United States""
  ["Abstracts"]=>
  string(5) ""(SLA)"
"
}
array(6) {
  ["No"]=>
  string(3) "104"
  ["Paper_id"]=>
  string(6) "TU5A-3"
  ["Title"]=>
  string(40) "a2"
  ["Author"]=>
  string(20) "DEF"
  ["Aff_list"]=>
  string(48) ""University of Alcala, Alcala de Henares, Spain""
  ["Abstracts"]=>
  string(9) ""Microwave"
"
}

请注意,作者的值已与主键“否”合并。有人可以帮我解决这个问题吗?

我试过这样做:

foreach($paper_info as $element) {
    foreach($element as $v) {
        $id = $element['No'];
        if (!isset($out[$id])) {
            $out[$id] = [
                'No' => $element['No'],
                'Paper_id' => $element['Paper_id'],
                'Title' => $element['Title'],
                'Authors' => [],
                'Aff_list' => $element['Aff_list'],
                'Abstracts' => $element['Abstracts']
            ];
        }
        $out[$id]['Authors'][] = ['Authors' => $element['Author']];
    }
}

【问题讨论】:

  • 您尝试的代码输出有什么问题?除了 out 变量缺少 $
  • 它的打印空数组! :(
  • 为什么101的title在合并a1和a2时变成""a-1"?!?为什么104的title原来是a3时变成a2?!?这不是一个好的minimal reproducible example。

标签: php arrays merge grouping


【解决方案1】:

您可以使用通用函数:

function _group_by($array, $key) {
    $return = array();
    foreach($array as $val) {
        $return[$val[$key]][] = $val;
    }
    return $return;
}

我添加了一些示例代码进行测试

<?php

$list= [
[   'No' => 101,
    'Paper_id' => 'WE3P-1',
    'Title' => "a1",
    'Author' => 'ABC',
    'Aff_list' => "University of South Florida, Tampa, United States",
    'Abstracts' => "SLA"
] ,
[   'No' => 101,
    'Paper_id' => 'WE3P-1',
    'Title' => "a2",
    'Author' => 'DEF',
    'Aff_list' => "University of South Florida, Tampa, United States",
    'Abstracts' => "SLA"
] ,
[    'No' => 104, 
    'Paper_id' => 'TUSA-3',
    'Title' => "a3",
    'Author' => 'GH1',
    'Aff_list' => "University of Alcala, Alcala de Henares, Spain",
    'Abstracts' => "Microwave"
] ];

print_r(_group_by($list, 'No'));

【讨论】:

    【解决方案2】:

    您问题中的数据格式不明确,但假设 $paper_info 的结构如下所示,这应该可以为您提供所需的输出。

    $paper_info = array(
        array(
            'No' => "101",
            'Paper_id' => "WE3P-1",
            'Title' =>"An Electrically-Small, 3-D Cube Antenna Fabricated with Additive Manufacturing",
            'Author' => "Ibrahim Nassar",
            ...
        ),
        array(
            'No' => "101",
            ...
            'Author' => "Thomas Weller",
            ...
        )
    );
    
    $out = array();
    foreach($paper_info as $paper) {
        $id = $paper['No'];
        if (!isset($out[$id])) {
            $out[$id] = $paper;
            $out[$id]['Author'] = array();
        }
        $out[$id]['Author'][] = $paper['Author'];
    }
    

    您还应该在开发环境中打开警告并显示错误。我有一种感觉,它会帮助你。在开发过程中,您可以配置您的 php.ini,或者在您的 php 脚本的开头插入此代码。只需确保在投入生产之前将其删除即可。

    error_reporting(E_ALL);
    ini_set('display_errors', '1');
    

    【讨论】:

    • 它的意思是:警告:非法字符串偏移 'No' 非法字符串偏移 'Author'
    • 这意味着您的数据不是我上面假设和指定的格式。如果您在问题中提供了一个有效的代码示例,我会提供帮助,该示例将以正确的格式创建变量 $paper_info。
    • $paper_info 是一个数组数组,例如 'No' => $a (这是一个 nos 数组),'Paper_id' =>$b (ids 数组).. 其他所有类似键
    • 如果您提到的错误首先发生在$id = $paper['No'] 行,则表明$paper_info 实际上是一个字符串数组。
    【解决方案3】:

    感谢crafter 提供了很棒的功能,如果有人需要为多个键分组,我将crafter 功能编辑为:

    function _group_by($array, $keys=array()) {
        $return = array();
        foreach($array as $val){
            $final_key = "";
            foreach($keys as $theKey){
                $final_key .= $val[$theKey] . "_";
            }
            $return[$final_key][] = $val;
        }
       return $return;
    }
    

    【讨论】:

      【解决方案4】:

      感谢火山口和法比奥的回答。我更新了代码以检查键的大小是否不大于一 (1),不会附加下划线。

      function _group_by($array, $keys=array()) {
          $return = array();
          $append = (sizeof($keys) > 1 ? "_" : null);
          foreach($array as $val){
              $final_key = "";
              foreach($keys as $theKey){
                  $final_key .= $val[$theKey] . $append;
              }
              $return[$final_key][] = $val;
          }
          return $return;
      }
      

      【讨论】:

        【解决方案5】:

        我写了另一个版本的 Crafter 的答案是从实际数组中删除给定的键。可以帮助别人。

            public function _group_by($array, $key) {
                $return = array();
                foreach($array as $val) {
                    $return[$val[$key]] = $val;
                    unset($return[$val[$key]][$key]);
                }
                return $return;
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-09-04
          • 2018-11-23
          • 1970-01-01
          • 2018-10-26
          • 1970-01-01
          • 2023-03-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多