Search code examples
phplaravelgroupingcollectdelimited

Group Laravel collection results by one column, retain the first item of each group and create comma-separated value from another column in the group


I have a collection with duplicate results, but with different data in a related field. I want to eliminate duplicates, but keep that other data by combining the value of that field. I cant seem to find a good way to do this. My result set looks like:

"bankers" => Collection {#663 ▼
  #items: array:5 [▼
    0 => Collection {#465 ▼
      #items: array:5 [▼
        "banker_id" => 13
        "banker_name" => "John Banker"
        "type" => "lending"
        "deal_score" => 1
      ]
    }
    1 => Collection {#455 ▼
      #items: array:5 [▼
        "banker_id" => 62667
        "banker_name" => "Harvey Aandreau"
        "type" => "lending"
        "deal_score" => 0
      ]
    }
    2 => Collection {#419 ▼
      #items: array:6 [▼
        "banker_id" => 13
        "banker_name" => "John Banker"
        "type" => "quotes"
        "deal_score" => 1
      ]
    }
    3 => Collection {#410 ▼
      #items: array:6 [▼
        "banker_id" => 297
        "banker_name" => "Melissa Jablonsky"
        "type" => "quotes"
        "deal_score" => 1
      ]
    }
  ]
}

I want to remove the second duplicate "John Banker", but append the value of the "type" field to the previous record, like:

"bankers" => Collection {#663 ▼
  #items: array:5 [▼
    0 => Collection {#465 ▼
      #items: array:5 [▼
        "banker_id" => 13
        "banker_name" => "John Banker"
        "type" => "lending, quotes"
        "deal_score" => 1
      ]
    }
    1 => Collection {#455 ▼
      #items: array:5 [▼
        "banker_id" => 62667
        "banker_name" => "Harvey Aandreau"
        "type" => "lending"
        "deal_score" => 0
      ]
    }
    3 => Collection {#410 ▼
      #items: array:6 [▼
        "banker_id" => 297
        "banker_name" => "Melissa Jablonsky"
        "type" => "quotes"
        "deal_score" => 1
      ]
    }
  ]
}

I need to preserve the current order. "type" field can be changed to an array if needed.


Solution

  • Thanks to Joseph Silber for the following suggestion:

    $bankers->groupBy('banker_name')->map(function ($bankers) {
        return array_merge($banker[0]->all(), [
            'type' => $bankers->pluck('type')->implode(',');
        ]);
    });