javascript LoDash - 如何通过公共键将一个集合值推送到另一个集合中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30946055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 12:58:58  来源:igfitidea点击:

LoDash - How to push one collections values into another via common key

javascriptarraysmultidimensional-arraylodash

提问by webmaster_sean

I have two collections.

我有两个收藏。

var a = 
[
 {unique_id: "001", state: "CO"},
 {unique_id: "001", state: "TX"},
 {unique_id: "001", state: "CC"},
 {unique_id: "002", state: "CC"},
 {unique_id: "002", state: "NY"}
]

And

var b = 
[
 {unique_id: "001", states:[]},
 {unique_id: "002", states:[]}
]

And I want to get:

我想得到:

var b = 
[
 {unique_id: "001", states:["CO","TX","CC"]},
 {unique_id: "002", states:["CC","NY"]}
]

I should mention that the "b" array has to stay in the same order it's in AND some of the unique_id's don't have a value.

我应该提到“b”数组必须保持与它所在的顺序相同,并且一些 unique_id 没有值。

I've been trying to use LoDash https://lodash.com/- so if anyone can solve this with LoDash that would be awesome!

我一直在尝试使用 LoDash https://lodash.com/- 所以如果有人能用 LoDash 解决这个问题,那就太棒了!

回答by Pavan Ravipati

The time complexity of this solution is suboptimal ( O(n^2) ), but it might help you think of ways to match pushing the values into "b":

这个解决方案的时间复杂度是次优的( O(n^2) ),但它可能会帮助你想出匹配将值推入“b”的方法:

_.forEach(a, function(element1){
  _.forEach(b, function(element2){
    if (element2.unique_id === element1.unique_id) {
     element2.states.push(element1.state);
    }
  });
});

Perhaps a better solution might be to index your objects in b by their unique id using lodash's _.indexBymethod. For example you can index your objects in b as follows:

也许更好的解决方案可能是使用 lodash 的_.indexBy方法通过它们的唯一 id 索引 b 中的对象。例如,您可以按如下方式在 b 中索引您的对象:

var c = _.indexBy(b, 'unique_id')

Which will result in:

这将导致:

{001:{unique_id: "001", states:[]}, 002: {unique_id: "002", states:[]}}

Since the objects in our c array are pointing to the same objects in memory as those in our b array, we can directly mutate our objects in c and b will reference those updated objects in memory. So:

由于 c 数组中的对象与 b 数组中的对象指向内存中的对象相同,因此我们可以直接改变 c 中的对象,b 将引用内存中更新的对象。所以:

_.forEach(a, function(element1){
  if (element1.unique_id in c) {
    c[element1.unique_id].states.push(element1.state);
  }
})

Now if we take a look at our b array, we'll see that the value is:

现在,如果我们看看我们的 b 数组,我们会看到它的值是:

var b = 
[
 {unique_id: "001", states:["CO","TX","CC"]},
 {unique_id: "002", states:["CC","NY"]}
]

The time complexity of this solution should be close to O(n), which is much better than using the nested _.forEachapproach. Code snippet:

这个解决方案的时间复杂度应该接近 O(n),这比使用嵌套的_.forEach方法要好得多。代码片段:

var a = 
[
 {unique_id: "001", state: "CO"},
 {unique_id: "001", state: "TX"},
 {unique_id: "001", state: "CC"},
 {unique_id: "002", state: "CC"},
 {unique_id: "002", state: "NY"}
];

var b = 
[
 {unique_id: "001", states:[]},
 {unique_id: "002", states:[]}
];

var c = _.indexBy(b, 'unique_id');

_.forEach(a, function(element1){
  if (element1.unique_id in c) {
    c[element1.unique_id].states.push(element1.state);
  }
});

document.writeln(JSON.stringify(b))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.9.3/lodash.js"></script>

回答by Adam Boduch

groupBy()and map()are your friends:

groupBy()map()是你的朋友:

_(a).groupBy('unique_id')
    .map(function(item, key) {
        return {
            unique_id: key,
            states: _.pluck(item, 'state')
        };
    })
    .value()

You're basically grouping the states by their unique_id, then mapping that object to an array where each item has the structure you need.

您基本上是按状态对状态进行分组unique_id,然后将该对象映射到一个数组,其中每个项目都具有您需要的结构。