根据同一数组中的另一个唯一值将一组值推送到数组

Push a set of values to an array based on another unique value in the same array

问题背景

您好,我有以下剧组成员:

array:7 [▼
  0 => array:6 [▼
    "credit_id" => "52fe49dd9251416c750d5e9d"
    "department" => "Directing"
    "id" => 139098
    "job" => "Director"
    "name" => "Derek Cianfrance"
    "profile_path" => "/zGhozVaRDCU5Tpu026X0al2lQN3.jpg"
  ]
  1 => array:6 [▼
    "credit_id" => "52fe49dd9251416c750d5ed7"
    "department" => "Writing"
    "id" => 139098
    "job" => "Story"
    "name" => "Derek Cianfrance"
    "profile_path" => "/zGhozVaRDCU5Tpu026X0al2lQN3.jpg"
  ]
  2 => array:6 [▼
    "credit_id" => "52fe49dd9251416c750d5edd"
    "department" => "Writing"
    "id" => 132973
    "job" => "Story"
    "name" => "Ben Coccio"
    "profile_path" => null
  ]
  3 => array:6 [▼
    "credit_id" => "52fe49dd9251416c750d5ee3"
    "department" => "Writing"
    "id" => 139098
    "job" => "Screenplay"
    "name" => "Derek Cianfrance"
    "profile_path" => "/zGhozVaRDCU5Tpu026X0al2lQN3.jpg"
  ]
  4 => array:6 [▼
    "credit_id" => "52fe49dd9251416c750d5ee9"
    "department" => "Writing"
    "id" => 132973
    "job" => "Screenplay"
    "name" => "Ben Coccio"
    "profile_path" => null
  ]
  5 => array:6 [▼
    "credit_id" => "52fe49dd9251416c750d5eef"
    "department" => "Writing"
    "id" => 1076793
    "job" => "Screenplay"
    "name" => "Darius Marder"
    "profile_path" => null
  ]
  11 => array:6 [▼
    "credit_id" => "52fe49de9251416c750d5f13"
    "department" => "Camera"
    "id" => 54926
    "job" => "Director of Photography"
    "name" => "Sean Bobbitt"
    "profile_path" => null
  ]
]

如您所见,这是我通过 TMDb API 获得的学分列表。构建上述数组的第一步是过滤掉所有我不想显示的职位,我是这样做的:

$jobs = [ 'Director', 'Director of Photography', 'Cinematography', 'Cinematographer', 'Story', 'Short Story', 'Screenplay', 'Writer' ];

$crew = array_filter($tmdbApi, function ($crew) use ($jobs) {
    return array_intersect($jobs, $crew);
});

我的问题

我想弄清楚如何将上述结果更进一步并结合 jobs 其中 id 是相同的,以便最终得到这样的结果,因为示例:

array:7 [▼
  0 => array:6 [▼
    "credit_id" => "52fe49dd9251416c750d5e9d"
    "department" => "Directing"
    "id" => 139098
    "job" => "Director, Story, Screenplay"
    "name" => "Derek Cianfrance"
    "profile_path" => "/zGhozVaRDCU5Tpu026X0al2lQN3.jpg"
  ]

我也考虑过在我的逻辑中放弃这样做,而是在我的 blade 模板中这样做,但我不确定如何实现。

你会如何完成这个?

由于您正在尝试编辑数组元素及其大小,我相信 array_map()array_filter() 不会是解决此问题的方法。

这是我能想到的...

$jobs = [
  'Director', 'Director of Photography', 'Cinematography',
  'Cinematographer', 'Story', 'Short Story', 'Screenplay', 'Writer'
];

$crew = [];

foreach($tmdbApi as $key => $member) {
  if($member['id'] == $id && in_array($member['job'], $jobs)) {
    if(!isset($crew[$key]))  {
      $crew[$key] = $member;
    } else {
      $crew_jobs = explode(', ', $crew[$key]['job']);
      if(!in_array($member['job'], $crew_jobs)) {
        $crew_jobs[] = $member['job'];
      }
      $crew[$key]['job'] = implode(', ', $crew_jobs);
    }
  }
}

希望这能回答您的问题:)

在这种情况下,您可以很好地使用 Laravel 的 Collection,它有很多方法可以在这种情况下为您提供帮助。

首先,将此数组(您已根据职位筛选的数组)转换为集合:

$collection = collect($crew);

其次,按 ids:

将此集合分组
$collectionById = $collection->groupBy('id');

现在,结果按 id 分组并转换为集合,其中 对应于id,值是 'matching' 结果的数组。有关它的更多信息 here

最后,只是一个简单的脚本,它遍历每个 id 的所有结果并组合 job 字段:

$combinedJobCollection = $collectionById->map(function($item) {
    // get the default object, in which all fields match
    // all the other fields with same ID, except for 'job'
    $transformedItem = $item->first();

    // set the 'job' field according all the (unique) job
    // values of this item, and implode with ', '
    $transformedItem['job'] = $item->unique('job')->implode('job', ', ');

    /* or, keep the jobs as an array, so blade can figure out how to output these
    $transformedItem['job'] = $item->unique('job')->pluck('job');
    */

    return $transformedItem;
})->values();
// values() makes sure keys are reordered (as groupBy sets the id
// as the key)

此时返回此Collection:

Collection {#151 ▼
  #items: array:4 [▼
    0 => array:6 [▼
      "credit_id" => "52fe49dd9251416c750d5e9d"
      "department" => "Directing"
      "id" => 139098
      "job" => "Director, Story, Screenplay"
      "name" => "Derek Cianfrance"
      "profile_path" => "/zGhozVaRDCU5Tpu026X0al2lQN3.jpg"
    ]
    1 => array:6 [▼
      "credit_id" => "52fe49dd9251416c750d5edd"
      "department" => "Writing"
      "id" => 132973
      "job" => "Story, Screenplay"
      "name" => "Ben Coccio"
      "profile_path" => null
    ]
    2 => array:6 [▼
      "credit_id" => "52fe49dd9251416c750d5eef"
      "department" => "Writing"
      "id" => 1076793
      "job" => "Screenplay"
      "name" => "Darius Marder"
      "profile_path" => null
    ]
    3 => array:6 [▼
      "credit_id" => "52fe49de9251416c750d5f13"
      "department" => "Camera"
      "id" => 54926
      "job" => "Director of Photography"
      "name" => "Sean Bobbitt"
      "profile_path" => null
    ]
  ]
}

注意:要将此集合用作数组,请使用:

$crew = $combinedJobCollection->toArray();

有多种方法可以实现此目的,例如:search重叠 ID 的数组,但我认为这是实现此目的的最简单方法。

祝你好运!