【问题标题】:Push a set of values to an array based on another unique value in the same array根据同一数组中的另一个唯一值将一组值推送到数组
【发布时间】:2016-11-28 06:21:24
【问题描述】:

问题背景

您好,我有以下电影摄制组成员:

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

我的问题

我想弄清楚如何将上述结果更进一步,并将jobsid相同的地方结合起来,最终得到这样的结果,例如:

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

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

你将如何做到这一点?

【问题讨论】:

    标签: php laravel blade


    【解决方案1】:

    在这种情况下你可以很好地使用 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 的数组,但我认为这是实现这一点的最简单方法。

    祝你好运!

    【讨论】:

    • 哇!这太好了,非常感谢,我仍然不熟悉 Laravel 的 collection() 功能。这太棒了。
    • 是的。您可能会考虑删除链接的implode 方法并将其替换为pluck('job')。这样,数据将保留为数组,您可以选择如何在刀片模板中输出这些作业,因此也可以 - 例如 - 在某种列表中输出作业,而不是逗号分隔的静态字符串.显示数据当然是 Blade 的工作。
    • 我已将此添加到我的答案中。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2014-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-15
      • 2021-06-20
      • 1970-01-01
      • 1970-01-01
      • 2017-03-02
      相关资源
      最近更新 更多