简体   繁体   中英

Group subarray data by one column and form comma-separated values from the secondary value in each group

I have a two dimensional array which needs to be restructured. Rows must be grouped by date values, and within each group, the name values should be formed into a single comma-delimited string.

My input:

$missedFridgeLog = [
    [
        "date" => "01/01/18",
        "name" => "Medicine"
    ],
    [
        "date" => "01/01/18",
        "name" => "Drugs"
    ],
    [
        "date" => "02/01/18",
        "name" => "Medicine"
    ],
    [
        "date" => "02/01/18",
        "name" => "Drugs"
    ]
];

I have tried implementing a solution from Implode or join multidimentional array with comma , but it did not work as desired.

Desired output:

[
    [
        'date' => '01/01/18',
        'name' => 'Medicine,Drugs',
    ],
    [
        'date' => '02/01/18',
        'name' => 'Medicine,Drugs',
    ]
]
$missedFridgeLog = [
    [
        "date" => "01/01/18",
        "name" => "Medicine"
    ],[
        "date" => "01/01/18",
        "name" => "Drugs"
    ]
    [
        "date" => "02/01/18",
        "name" => "Medicine"
    ],
    [
        "date" => "02/01/18",
        "name" => "Drugs"
    ]
];


$byDates = [];
foreach ($missedFridgeLog as $mfg) {
    $byDates[$mfg['date']][] = $mfg['name'];
}

$res = [];
foreach ($byDates as $date => $name) {
    $res[] = [
        'name' => join(',',$name),
        'date' => $date
    ];
}
var_dump($res);

You need to search key, value pair everytime you make a insert or update to result array. use this function() to search associate array . If match then update with additional name info else make a new insert to result array.

 function filter_array($array){    

///$array  your previous array data    
$result = array();

foreach($array["missedFridgeLog"] as $m){
    $flag = true;
    foreach($result as $k=>$r) {
        if (is_in_array($r, "date", $m["date"]) == "yes") {
            $result[$k]["name"] = $r["name"] . ',' . $m["name"];
            $flag = false;
            break;
        }
    }
    if($flag==true){
        $result[] = $m;
    }
}

return array("missedFridgeLog"=>$result);
}


function is_in_array($array, $key, $key_value){
$within_array = 'no';
foreach( $array as $k=>$v ){
    if( is_array($v) ){
        $within_array = is_in_array($v, $key, $key_value);
        if( $within_array == 'yes' ){
            break;
        }
    } else {
        if( $v == $key_value && $k == $key ){
            $within_array = 'yes';
            break;
        }
    }
}
return $within_array;
}

May be this is not the best way to do this, but it will help

$arr['missedFridgeLog'] = [
        [
        'date' => '01/01/18',
        'name' => 'Medicine1'
    ],
        [
        'date' => '02/01/18',
        'name' => 'New Medicine2'
    ],
        [
        'date' => '01/01/18',
        'name' => 'Drugs1'
    ],
        [
        'date' => '02/01/18',
        'name' => 'Medicine2'
    ],
        [
        'date' => '01/01/18',
        'name' => 'New Drugs1'
    ],
        [
        'date' => '02/01/18',
        'name' => 'Drugs2'
    ]
];

echo "<pre>";

$new_arr = array();
$date = array();

foreach ($arr['missedFridgeLog'] as $k => $a) {
    if (in_array($a['date'], $date))
        continue;
    $new_arr[$k]['name'] = $a['name'];
    $new_arr[$k]['date'] = "";
    foreach ($arr[missedFridgeLog] as $key => $val) {
        if ($key != $k) {
            if ($a['date'] == $val['date']) {
                $date[] = $new_arr[$k]['date'] = $a['date'];
                $new_arr[$k]['name'] .= ", " . $val['name'];
            }
        }
    }
    if (empty($new_arr[$k]['date']))
        unset($new_arr[$k]);
}

print_r($new_arr);

You can try below:-

Input array:-

$chkArray = [
  'missedFridgeLog' => [
    '0' => [
      'date' => '01/01/18',
      'name' => 'Medicine'
    ],
    '1' => [
      'date' => '01/01/18',
      'name' => 'Drugs'
    ],
    '2' => [
      'date' => '02/01/18',
      'name' => 'Medicine'
    ],
    '3' => [
      'date' => '02/01/18',
      'name' => 'Drugs'
    ],
    '4' => [
      'date' => '02/01/18',
      'name' => 'My Drugs'
    ]
  ]

];

$i = 0;
$finalarray = array();
foreach($chkArray['missedFridgeLog'] as $key=>$value) {
  $checkExist = array_search($value['date'], array_column($finalarray, 'date'), true);
  if($checkExist !== false) {
     $finalarray[$checkExist]['name'] = $finalarray[$checkExist]['name'].','.$value['name'];
  }
  else {
  $finalarray[$i]['date'] = $value['date'];
  $finalarray[$i]['name'] = $value['name'];
  $i++;
  }

}

print_r($finalarray);

OutPut:-

Array
(
    [0] => Array
        (
            [date] => 01/01/18
            [name] => Medicine,Drugs
        )

    [1] => Array
        (
            [date] => 02/01/18
            [name] => Medicine,Drugs,My Drugs
        )

)

Do not use:

  1. More than one loop,
  2. Nested loops,
  3. in_array() , or
  4. array_search() .

You only need one loop to apply temporary grouping keys. When a date/group is encountered after the first time, append its name value to the group's name value. When finished iterating, re-index the array.

Code: ( Demo )

$result = [];
foreach ($missedFridgeLog as $row) {
    if (!isset($result[$row['date']])) {
        $result[$row['date']] = $row;
    } else {
        $result[$row['date']]['name'] .= ",{$row['name']}";
    }
}
var_export(array_values($result));

Output:

array (
  0 => 
  array (
    'date' => '01/01/18',
    'name' => 'Medicine,Drugs',
  ),
  1 => 
  array (
    'date' => '02/01/18',
    'name' => 'Medicine,Drugs',
  ),
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM