2016-11-26 2 views
0

Вопрос фон

Здравствуйте, У меня есть следующий массив членов экипажа фильма:Нажимаем набор значений массива на основе другого уникального значения в том же массиве

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

Как вы можете видеть это это список кредитов, которые я получаю через API TMDb. Первый шаг построения выше массив был отфильтровать все рабочие места, которые я не хочу показывать, вот как я это сделал:

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

Я также считал канав, делая это в моей логике и вместо делаю это в моем клипе t эмблема, но я не уверен, как это достичь.

Как бы вы это сделали?

ответ

1

Вы могли хорошо использовать Коллекцию Laravel в такой ситуации, которая имеет большое количество методы, которые помогут вам в этом случае.

Во-первых, превратить этот массив (тот, который вы уже отфильтрованы на рабочие места) к коллекции:

$collection = collect($crew); 

Во-вторых, группа этой подборке по его id S:

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

Теперь, результаты сгруппированы поid и преобразованы в коллекцию, в которой ключи соответствуют идентификатору, а значение представляет собой массив результатов сопоставления. Подробнее об этом 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 {#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 массив для перекрытия идентификаторов, но я думаю, что это самый простой способ достичь этого.

Goodluck!

+0

Wow! Это отлично, спасибо большое, я до сих пор не знаком с функциональностью Laravel's collection(). Это потрясающе. – gmask

+0

Да, это так. Вы можете подумать об удалении прикованного метода 'implode' и заменить его' pluck ('job') '. Таким образом, данные будут оставаться в виде массива, и вы можете выбрать способ вывода этих заданий в шаблон вашего клинка, так что также можно, например, вывести задания в некотором виде вместо статической строки, разделенной запятой , Отображение данных - это, конечно же, работа Blade. –

+0

Я добавил это к своему ответу. –

1

Поскольку вы пытаетесь редактировать элементы массива и его размер, я считаю, что 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); 
    } 
    } 
} 

Надеется, что это ответ на ваш вопрос :)