使用两个不同的数组创建一个分组数组

时间:2020-12-03 12:56:20

I have below two arrays:

我有两个数组:

array1 = [{
   "type":"test",
   "name":"name1"},
 {
   "type":"dev",
    "name":"name2"}]

array2=[{
         "type":"test",
         "name":"name3"},
        {
         "type":"dev",
         "name":"name4"},
        {
         "type":"prod",
         "name":"name5"}]

I want to group two arrays with "type" and create a new array something like this:

我想用“type”对两个数组进行分组,并创建一个像这样的新数组:

finalArray=[{
             "type":"test",
             "info":[{
                      "type":"test",
                      "name":"name1"}],
                    [{
                      "type":"test",
                      "name":"name3"
                    }]},
             {
              "type":"dev",
              "info":[{
                       "type":"dev",
                       "name":"name2"}],
                     [{
                       "type":"dev",
                       "name":"name4"}]},
             {
              "type":"prod",
              "info":[],
                     [{
                       "type":"prod",
                        "name":"name5"}]
               }]

Is there anyway that I can achieve this using javascript, angularjs2, lodash, jquery. I am able to group and create new object as mentioned in using lodash .groupBy. how to add your own keys for grouped output?

无论如何,我可以使用javascript,angularjs2,lodash,jquery实现这一点。我可以使用lodash .groupBy中提到的分组和创建新对象。如何为分组输出添加自己的密钥?

But only thing is always I want to push the data from second array in index=1 of "info" and first one to index=0. If any of the array does not have a "type" then the "info" array should have empty/null values.

但唯一的事情总是我想从第二个数组推送“info”的index = 1中的数据,第一个数据推送到index = 0。如果任何数组没有“类型”,那么“info”数组应该具有空/空值。

4 个解决方案

#1


1  

It's possible to achieve the result you want in javascript, or using helper like lodash. The last part of your question is hard to understand. If an array doesn't have "type", how would you group them. Please provide clearer explanation or modify your expected input and output.

可以在javascript中实现您想要的结果,或者使用像lodash这样的帮助器。你问题的最后一部分很难理解。如果数组没有“类型”,您将如何对它们进行分组。请提供更清晰的解释或修改您的预期输入和输出。

[Updated] Thanks for your explanation. This is the solution using plain javascript.

[更新]感谢您的解释。这是使用普通javascript的解决方案。

// get uniques type from two arrays
const uniqueTypes = new Set(array1
                          .concat(array2)
                          .map(x => x.type));

// loop the types, find item in both array
// group it
let result = Array.from(uniqueTypes).reduce((acc, curr) => {
    const item1 = array1.find(x => x.type === curr);
    const item2 = array2.find(x => x.type === curr);

    const info1 = item1 ? [item1] : [];
    const info2 = item2 ? [item2] : [];

    acc = acc.concat({ type: curr, info: [info1, info2] });

    return acc;
}, []);


console.log(result);

jsbin here: https://jsbin.com/mobezogaso/edit?js,console

jsbin在这里:https://jsbin.com/mobezogaso/edit?js,console

#2


2  

use _.mapValues to iterate object values with key accessing

使用_.mapValues通过键访问来迭代对象值

var res =  _.chain(array1)
    .concat(array2)
    .groupBy('type')
    .mapValues(function(val, key) {
        return {
            type: key,
            info: val
        };
    })
    .values()
    .value();

#3


1  

Here's a working solution :). Hope it helps!

这是一个有效的解决方案:)。希望能帮助到你!

var array1 = [
{
"type":"test",
"name":"name1"
},
{
"type":"dev",
"name":"name2"
}
]

var array2 = [
{
"type":"test",
"name":"name3"
},
{
"type":"dev",
"name":"name4"
},
{
"type":"prod",
"name":"name5"
}
]


var newArray = array1.concat(array2);
var arr1 = [];
var arr2 = [];
var arr3 = [];
var arrTypes = [];
var finalArray = [];
var someArray = [];

for(var i in newArray)
{
 if (arrTypes.indexOf(newArray[i].type) === -1){
   arrTypes.push(newArray[i].type);
 }

 if(newArray[i].type === "test"){
   arr1.push(newArray[i]);
 }
 else if(newArray[i].type === "dev"){
   arr2.push(newArray[i]);
 }
 else if(newArray[i].type === "prod"){
   arr3.push(newArray[i]);
 }
}
someArray.push(arr1);
someArray.push(arr2);
someArray.push(arr3);

for(var j = 0; j < someArray.length; j++){
	finalArray.push({
		"type": arrTypes[j],
		"info": someArray[j]
	});
}
console.log(finalArray);

#4


0  

And a short (unreadable?) ES6 solution:

还有一个简短的(不可读的?)ES6解决方案:

  1. Concat the arrays
  2. Concat数组
  3. Reduce the array into a Map object, with the type as the key
  4. 将数组缩减为Map对象,类型为键
  5. Get the entries iterator - key (type) - value (array of objects)
  6. 获取条目迭代器 - 键(类型) - 值(对象数组)
  7. Use spread to convert the entry iterator to an array
  8. 使用spread将条目迭代器转换为数组
  9. Array#Map the array of entries to the type/info objects
  10. Array#将条目数组映射到类型/ info对象

const array1 = [{"type":"test","name":"name1"},{"type":"dev","name":"name2"}];
const array2=[{"type":"test","name":"name3"},{"type":"dev","name":"name4"},{"type":"prod","name":"name5"}];

const result = [...array1.concat(array2).reduce((r, o) => {
    r.has(o.type) ? r.get(o.type).push(o) : r.set(o.type, [o]);
    return r;
  }, new Map).entries()]
  .map(([type, info]) => ({
    type, info
  }));

console.log(result);

#1


1  

It's possible to achieve the result you want in javascript, or using helper like lodash. The last part of your question is hard to understand. If an array doesn't have "type", how would you group them. Please provide clearer explanation or modify your expected input and output.

可以在javascript中实现您想要的结果,或者使用像lodash这样的帮助器。你问题的最后一部分很难理解。如果数组没有“类型”,您将如何对它们进行分组。请提供更清晰的解释或修改您的预期输入和输出。

[Updated] Thanks for your explanation. This is the solution using plain javascript.

[更新]感谢您的解释。这是使用普通javascript的解决方案。

// get uniques type from two arrays
const uniqueTypes = new Set(array1
                          .concat(array2)
                          .map(x => x.type));

// loop the types, find item in both array
// group it
let result = Array.from(uniqueTypes).reduce((acc, curr) => {
    const item1 = array1.find(x => x.type === curr);
    const item2 = array2.find(x => x.type === curr);

    const info1 = item1 ? [item1] : [];
    const info2 = item2 ? [item2] : [];

    acc = acc.concat({ type: curr, info: [info1, info2] });

    return acc;
}, []);


console.log(result);

jsbin here: https://jsbin.com/mobezogaso/edit?js,console

jsbin在这里:https://jsbin.com/mobezogaso/edit?js,console

#2


2  

use _.mapValues to iterate object values with key accessing

使用_.mapValues通过键访问来迭代对象值

var res =  _.chain(array1)
    .concat(array2)
    .groupBy('type')
    .mapValues(function(val, key) {
        return {
            type: key,
            info: val
        };
    })
    .values()
    .value();

#3


1  

Here's a working solution :). Hope it helps!

这是一个有效的解决方案:)。希望能帮助到你!

var array1 = [
{
"type":"test",
"name":"name1"
},
{
"type":"dev",
"name":"name2"
}
]

var array2 = [
{
"type":"test",
"name":"name3"
},
{
"type":"dev",
"name":"name4"
},
{
"type":"prod",
"name":"name5"
}
]


var newArray = array1.concat(array2);
var arr1 = [];
var arr2 = [];
var arr3 = [];
var arrTypes = [];
var finalArray = [];
var someArray = [];

for(var i in newArray)
{
 if (arrTypes.indexOf(newArray[i].type) === -1){
   arrTypes.push(newArray[i].type);
 }

 if(newArray[i].type === "test"){
   arr1.push(newArray[i]);
 }
 else if(newArray[i].type === "dev"){
   arr2.push(newArray[i]);
 }
 else if(newArray[i].type === "prod"){
   arr3.push(newArray[i]);
 }
}
someArray.push(arr1);
someArray.push(arr2);
someArray.push(arr3);

for(var j = 0; j < someArray.length; j++){
	finalArray.push({
		"type": arrTypes[j],
		"info": someArray[j]
	});
}
console.log(finalArray);

#4


0  

And a short (unreadable?) ES6 solution:

还有一个简短的(不可读的?)ES6解决方案:

  1. Concat the arrays
  2. Concat数组
  3. Reduce the array into a Map object, with the type as the key
  4. 将数组缩减为Map对象,类型为键
  5. Get the entries iterator - key (type) - value (array of objects)
  6. 获取条目迭代器 - 键(类型) - 值(对象数组)
  7. Use spread to convert the entry iterator to an array
  8. 使用spread将条目迭代器转换为数组
  9. Array#Map the array of entries to the type/info objects
  10. Array#将条目数组映射到类型/ info对象

const array1 = [{"type":"test","name":"name1"},{"type":"dev","name":"name2"}];
const array2=[{"type":"test","name":"name3"},{"type":"dev","name":"name4"},{"type":"prod","name":"name5"}];

const result = [...array1.concat(array2).reduce((r, o) => {
    r.has(o.type) ? r.get(o.type).push(o) : r.set(o.type, [o]);
    return r;
  }, new Map).entries()]
  .map(([type, info]) => ({
    type, info
  }));

console.log(result);