简体   繁体   English

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

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

Question background 问题背景

Hello, I have the following array of movie crew members: 您好,我有以下电影摄制组成员:

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
  ]
]

As you can see this is a list of credits I'm getting via the TMDb API. 如您所见,这是我通过TMDb API获得的积分列表。 The first step of building the above array was to filter out all jobs that I don't want to display, here's how I did that: 构建上述数组的第一步是过滤掉我不想显示的所有作业,这是我的操作方法:

$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);
});

My question 我的问题

I'd like to figure out how to take the above result one step further and combine jobs where the id is the same, so as to end up with something like this, for example: 我想弄清楚如何使上述结果更进一步,并合并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"
  ]

I have also considered ditching doing this in my logic and instead doing it in my blade template, but I'm not sure how to achieve that. 我也考虑过按照我的逻辑去做,而不是在我的刀片模板中去做,但是我不确定如何实现。

How would you accomplish this? 您将如何实现?

Since you are trying to edit the array elements and its size, I believe array_map() or array_filter() won't be a solution to this. 由于您正在尝试编辑数组元素及其大小,因此我相信array_map()array_filter()将不是解决方案。

This is what I could come up with... 这就是我能想到的...

$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);
    }
  }
}

Hope this answers your question :) 希望这能回答您的问题:)

You could nicely use Laravel's Collection in such a situation, which has a great number of methods which will help you in this case. 在这种情况下,您可以很好地使用Laravel的Collection,它有很多方法可以在这种情况下为您提供帮助。

First, turn this array (the one you already filtered on jobs) to a Collection: 首先,将此数组(您已经在作业中过滤的数组)转到集合:

$collection = collect($crew);

Second, group this Collection by it's id s: 其次,按id这个Collection分组:

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

Now, the results are grouped by the id and transformed to a Collection in which the keys correspond to the id, and the value an array of 'matching' results. 现在,将结果 id 分组,并转换为一个集合,其中对应于id,其值是一个“匹配”结果数组。 More info about it here . 有关此的更多信息。

Finally, just a easy script that iterates through all the results for each id and combines the job field: 最后,只是一个简单的脚本,它遍历每个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)

At this point, this Collection is returned: 此时,将返回此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
    ]
  ]
}

Note: to use this Collection as an array, use: 注意:将此Collection用作数组,请使用:

$crew = $combinedJobCollection->toArray();

There are multiple ways to achieve this, for example: search the array for overlapping id's, but I think this is the easiest way to achieve this. 有多种方法可以实现此目的,例如:在数组中search重叠的ID,但是我认为这是实现此目的的最简单方法。

Goodluck! 祝好运!

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

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