如何将一个数组转换为另一个数组

时间:2019-01-17 06:27:56

标签: javascript arrays

我没有一个数组:

const arr = [
  { name: "aa", type: "total", count: 28394 },
  { name: "aa", type: "featured", count: 4 },
  { name: "aa", type: "noAnswers", count: 5816 },
  { name: "ba", type: "total", count: 148902 },
  { name: "ba", type: "featured", count: 13 },
  { name: "ba", type: "noAnswers", count: 32527 },
  { name: "cc", type: "total", count: 120531 },
  { name: "cc", type: "featured", count: 6 },
  { name: "cc", type: "noAnswers", count: 24170 }
];


const arrResult = [
  { name: "aa", total: 28394, featured: 4, noAnswers: 5816 },
  { name: "ba", total: 148902, featured: 13, noAnswers: 32527 },
  { name: "cc", total: 120531, featured: 6, noAnswers: 24170 }
];

我想出了这段代码:

let output = [];

const unique = [...new Set(arr.map(item => item.name))];

for(const key of unique) {
  let result = arr.filter(x => {
    return x.name === key;
  });
  output.push({
    name: key,
    // need to get the rest of the properties here
    // total
    // featured
    // noAnswers
  });
}

我唯一不知道的一件事是如何获取属性名称。 有什么想法吗?

6 个答案:

答案 0 :(得分:5)

您可以尝试以下操作:

想法:

  • 创建一个hashMap,以便您可以通过name对对象进行分组。
  • 然后,向该组添加必要的属性。
  • 最后,循环遍历键并创建最终对象,并添加回name属性。

const arr = [ { name: "aa", type: "total", count: 28394 }, { name: "aa", type: "featured", count: 4 }, { name: "aa", type: "noAnswers", count: 5816 }, { name: "ba", type: "total", count: 148902 }, { name: "ba", type: "featured", count: 13 }, { name: "ba", type: "noAnswers", count: 32527 }, { name: "cc", type: "total", count: 120531 }, { name: "cc", type: "featured", count: 6 }, { name: "cc", type: "noAnswers", count: 24170 } ];

const hashMap = arr.reduce((acc, item) => {
  acc[item.name] = acc[item.name] || {};
  acc[item.name][item.type] = item.count;
  return acc;
}, {});

const result = Object.keys(hashMap).map((name) => Object.assign({}, {name}, hashMap[name] ));

console.log(result)


工作:

我正在做的是为每个新的name创建一个新的对象。因此,这是:acc[item.name] = acc[item.name] || {};检查条目是否不可用。

  • 如果不可用,请返回一个新对象。
  • 如果可用,返回相同对象的引用。

因此,对于任何给定的名称,您将仅引用相同的对象。

现在,这:acc[item.name][item.type] = item.count设置属性。当我们指的是同一对象时,您将属性设置在一个地方。因此,如果您有重复的条目,请说

[
    { name: "aa", type: "total", count: 28394 },
    { name: "aa", type: "total", count: 123},
]

输出将改为带有total: 123

因此,最后,您的结构如下:

{
  aa: {
    total: <something>,
    feature: <something>,
    ...
  }
}

现在您所要做的就是在此对象中合并名称并返回值。您还可以使用默认属性name创建对象(adiga 完成)。那是我在回答时没有想到的事情。因此,记分而不是回答。

答案 1 :(得分:2)

您可以像这样使用reducedestructuring

这个想法是用key作为name属性创建一个对象,并将值作为输出中需要的最终对象。因此,您可以简单地使用Object.values来获取最终数组:

const arr=[{name:"aa",type:"total",count:28394},{name:"aa",type:"featured",count:4},{name:"aa",type:"noAnswers",count:5816},{name:"ba",type:"total",count:148902},{name:"ba",type:"featured",count:13},{name:"ba",type:"noAnswers",count:32527},{name:"cc",type:"total",count:120531},{name:"cc",type:"featured",count:6},{name:"cc",type:"noAnswers",count:24170}];

const merged = arr.reduce((acc,{name,type,count}) =>
  ((acc[name] = acc[name] || {name})[type] = count, acc)
,{})

console.log(Object.values(merged))

这等效于:

const arr=[{name:"aa",type:"total",count:28394},{name:"aa",type:"featured",count:4},{name:"aa",type:"noAnswers",count:5816},{name:"ba",type:"total",count:148902},{name:"ba",type:"featured",count:13},{name:"ba",type:"noAnswers",count:32527},{name:"cc",type:"total",count:120531},{name:"cc",type:"featured",count:6},{name:"cc",type:"noAnswers",count:24170}];

/* Our goal is to create a merged object like this:
{
  "aa": {
    "name": "aa",
    "total": 28394,
    "featured": 4,
    "noAnswers": 5816
  },
  "ba": {
    "name": "ba",
    "total": 148902,
    ....
  },
  "cc": {
    "name": "cc",
     ......
  }
}

The advantage of using object accumulator is we can access it like this: acc[name]
*/

const merged = arr.reduce((acc, {name,type,count} /*Destructuring*/) => {
  /* if the accumulator doesn't have the current "name" key, 
   create new object
   else use the existing one;
   {name} is same as {name: name}
  */
  acc[name] = acc[name] || {name};
  
  /* To the inner object, 
      add a key with the "type" value and assign it to "count" value
  */
  acc[name][type] = count;
  
  // return the accumulator
  return acc;
}, {})

// use Object.values to get the value part of the merged obejct into an array
console.log(Object.values(merged))

答案 2 :(得分:1)

pip install tf-nightly-2.0-preview

只需添加此选项即可正常工作。但是,您的代码并不是最有效的。 根据名称进行哈希处理会使其更快

var op = {name : key};

  for(i=0; i < result.length; i++){
    op[result[i].type] = result[i].count;
  }

  output.push(op);

以下是最有效的方法:

const arr = [
  { name: "aa", type: "total", count: 28394 },
  { name: "aa", type: "featured", count: 4 },
  { name: "aa", type: "noAnswers", count: 5816 },
  { name: "ba", type: "total", count: 148902 },
  { name: "ba", type: "featured", count: 13 },
  { name: "ba", type: "noAnswers", count: 32527 },
  { name: "cc", type: "total", count: 120531 },
  { name: "cc", type: "featured", count: 6 },
  { name: "cc", type: "noAnswers", count: 24170 }
];

let output = [];

const unique = [...new Set(arr.map(item => item.name))];

for(const key of unique) {
  let result = arr.filter(x => {
    return x.name === key;
  });
  
  var op = {name : key};
  
  for(i=0; i < result.length; i++){
    op[result[i].type] = result[i].count;
  }
  
  output.push(op);
}

console.log(output);

答案 3 :(得分:0)

您可以使用JavaScript的find运算符从arrResult抓取所需的行,如下所示更改代码-

for(const key of unique) {
  let result = arr.filter(x => {
    return x.name === key;
  });
  var currResult = arrResult.find(x => x.name == key);
  output.push({
    name: key,
    // need to get the rest of the properties here
    total: currResult.total,
    featured: currResult.featured,
    noAnswers: currResult.noAnswers
  });
}

JSFiddle:https://jsfiddle.net/ashhaq12345/z8royg5w/

答案 4 :(得分:0)

const arr = [
  { name: "aa", type: "total", count: 28394 },
  { name: "aa", type: "featured", count: 4 },
  { name: "aa", type: "noAnswers", count: 5816 },
  { name: "ba", type: "total", count: 148902 },
  { name: "ba", type: "featured", count: 13 },
  { name: "ba", type: "noAnswers", count: 32527 },
  { name: "cc", type: "total", count: 120531 },
  { name: "cc", type: "featured", count: 6 },
  { name: "cc", type: "noAnswers", count: 24170 }
];

const names = [...new Set(arr.map(item => item.name))]
const output = {};

names.forEach(name => {output[name] = {}});

arr.forEach(item => {
  output[item.name][item.type] = item.count
});

const result = Object.entries(output).map(([name, rest]) => ({name, ...rest}))
console.log(result);

const arrResult = [
  { name: "aa", total: 28394, featured: 4, noAnswers: 5816 },
  { name: "ba", total: 148902, featured: 13, noAnswers: 32527 },
  { name: "cc", total: 120531, featured: 6, noAnswers: 24170 }
];

答案 5 :(得分:0)

您可以简单地使用for循环遍历数组并获取一个temp数组,获取地图并使用所需数据填充地图,然后将您的地图推入temp数组中,如下所示。

const arr = [
  { name: "aa", type: "total", count: 28394 },
  { name: "aa", type: "featured", count: 4 },
  { name: "aa", type: "noAnswers", count: 5816 },
  { name: "ba", type: "total", count: 148902 },
  { name: "ba", type: "featured", count: 13 },
  { name: "ba", type: "noAnswers", count: 32527 },
  { name: "cc", type: "total", count: 120531 },
  { name: "cc", type: "featured", count: 6 },
  { name: "cc", type: "noAnswers", count: 24170 }
];

let result = [];
for( var i = 0; i < arr.length; i++)
{
   let data = {};
   if( arr[i].type == 'total')
   {
      data.name = arr[i].name;
      data.total = arr[i].count;
      data.featured = arr[i+1].count;
      data.noAnswers = arr[i+2].count;
      result.push(data);
   }
}

console.log(result);