繁体   English   中英

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

[英]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);
});

我的问题

我想弄清楚如何使上述结果更进一步,并合并id相同的jobs ,从而得到这样的结果,例如:

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

我也考虑过按照我的逻辑去做,而不是在我的刀片模板中去做,但是我不确定如何实现。

您将如何实现?

由于您正在尝试编辑数组元素及其大小,因此我相信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);

其次,按id这个Collection分组:

$collectionById = $collection->groupBy('id');

现在,将结果 id 分组,并转换为一个集合,其中对应于id,其值是一个“匹配”结果数组。 有关此的更多信息。

最后,只是一个简单的脚本,它遍历每个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
    ]
  ]
}

注意:将此Collection用作数组,请使用:

$crew = $combinedJobCollection->toArray();

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

祝好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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