【问题标题】:Map array values to collection of items将数组值映射到项目集合
【发布时间】:2019-05-29 12:16:56
【问题描述】:

如何使用 laravel 集合优雅地执行以下操作?

$baseMap 的值映射为集合的键。

底图:

$baseMap = [
            'name' => 'new_name',
            'year' => 'new_year',
        ];

收藏:

 $items = collect([
            [
                'name' => 'name1',
                'year' => '1000',
                'not_in_basemap' => 'foo'
            ],
            [
                'name' => 'name2',
                'year' => '2000',
                'not_in_basemap' => 'foo'
            ],
            //...
        ]);

最终结果:

$result =[
            [
                'new_name' => 'name1',
                'new_year' => '1000',

            ],
            [
                'new_name'=> 'name2',
                'new_year' => '2000',

            ],
        ];

我知道如何用普通的 php 来做,只是想知道一个不错的集合版本会是什么。谢谢!

【问题讨论】:

  • 查看only() 方法。不确定语法,但类似于:$result = $items->only($base_map); 您可能必须使用 $items->only($base_map->toArray()); 将 $base_map 设为数组
  • @ourmandave :这是一个开始,但它只会删除键 not_in_baseMap ,它不会将项目中的键替换为 baseMap 中的值

标签: laravel laravel-5.7


【解决方案1】:

我试图找到收集方法或php函数,但没有成功。一些脏代码可以使用双方的不同键(项目和底图)。

$result = $items->map(function($item) use ($baseMap) {
    $array = [];

    foreach($baseMap as $oldKey => $newKey){
        if(isset($item[$oldKey])){
            $array[$newKey] = $item[$oldKey];
        }
    }

    return $array;
});

$result = $result->toArray();

【讨论】:

  • 是的,我得出了同样的结论。很可能是普通的旧php。感谢您的时间伙伴!
【解决方案2】:

感谢@vivek_23 和@IndianCoding 给我的想法,我最终得到了以下结果: 我做了一个小的编辑,以确保映射和项目键对齐。 所以你不必担心错位和所有在 laravel 集合中!


$baseMap = collect($baseMap)->sortKeys();

$result = $items->map(function ($item) use ($baseMap) {

            return $baseMap->values()
                ->combine(
                    collect($item)->sortKeys()->intersectByKeys($baseMap)
                )
                ->all();
        });

【讨论】:

    【解决方案3】:

    使用intersectByKeys 过滤您的baseMap 键和$items 值。

    $result = $items->map(function($item,$key) use ($baseMap){
        return array_combine(array_values($baseMap),collect($item)->intersectByKeys($baseMap)->all());
    });
    
    dd($result);
    

    更新:

    以纯粹的收集方式,

    $baseMapCollect = collect($baseMap);
    
    $result = $items->map(function($item,$key) use ($baseMapCollect){
        return $baseMapCollect->values()->combine(collect($item)->intersectByKeys($baseMapCollect->all())->values())->all();
    });
    
    dd($result);
    

    【讨论】:

    • 别担心,伙计,感谢您的意见!这里是你的结果集合 {#376 ▼ #items: array:2 [▼ 0 => array:2 [▼ "name" => "new_name" "year" => "new_year" ] 1 => array:2 [▼ "名称”=>“新名称”“年份”=>“新年份”]]}
    • 干得好,伙计!有趣的方法。谢谢
    • 是的,请做!
    • @Paolo_Mulder 通过集合策略更新了我的答案。
    【解决方案4】:

    这是我的两分钱,使用map。不知道您的收藏应该有多动态,但知道密钥我会执行以下操作:

    $baseMap = [
        'name' => 'new_name',
        'year' => 'new_year',
    ];
    
    $items = collect([
        [
          'name' => 'name1',
          'year' => '1000',
          'not_in_basemap' => 'foo'
        ],
        [
          'name' => 'name2',
          'year' => '2000',
          'not_in_basemap' => 'foo'
        ],
    
      ])->map(function($item, $key) use ($baseMap) {
            return [
                 $baseMap['name'] => $item['name'],
                 $baseMap['year'] => $item['year']
            ];
      });
    

    【讨论】:

    • 但你所说的动态是指内容,甚至键都会改变?因为只要这两个键都是nameyear,这将起作用。
    • 感谢您的回复,是的,它们将是动态的...底图将被设置为固定的类属性。其余的将需要是动态的......
    猜你喜欢
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    • 2016-01-13
    相关资源
    最近更新 更多