将数组数组转换为组合在一起的对象数组

时间:2018-10-04 18:58:48

标签: javascript arrays object

我有一个数组数组。如何将它们转换为组合在一起的对象数组?

var abc = [
  ['apple', 'fruit'], ['banana', 'fruit'], ['grapes', 'fruit'], ['red', 'color'], ['blue', 'color'], ['black', 'color']
]


abc = abc.map(function(item) {
  return {
    value: item[0],
    color: item[1]
  }
})

colors = abc.filter(function(item) {
  return item.color === 'color'
})

fruits = abc.filter(function(item) {
  return item.color === 'fruit'
})

var result = [{
  group: 'color',
  value: colors.map(function(item) {
    return item.value
  })
}, {
  group: 'fruit',
  value: fruits.map(function(item) {
    return item.value
  })
}]

console.log(result)

我的预期输出是:

var abc = [
{
    group: 'color',
    value: ['red', 'blue', 'black']
},
{
    group: 'fruit',
    value: ['apple', 'banana', 'grapes']
}]

有没有更简单的方法来实现这一目标?

我也可以使用lodash。请告知。

6 个答案:

答案 0 :(得分:4)

这是使用reducemap的方法。 reduce通过group执行映射到值数组的汇总。 Object.entries()map将此分组转换为所需的对象数组格式。

var abc = [
  ['apple', 'fruit'],
  ['banana', 'fruit'],
  ['grapes', 'fruit'],
  ['red', 'color'],
  ['blue', 'color'],
  ['black', 'color']
];

const result = Object.entries(
    abc.reduce((a, e) => {
      if (!(e[1] in a)) {
        a[e[1]] = [];
      }

      a[e[1]].push(e[0]);
      return a;
    }, {})
  ).map(e => ({group: e[0], value: e[1]}))
;

console.log(result);

答案 1 :(得分:2)

您可以按索引将lodash与分组,并映射另一个索引的值。

var data = [['apple', 'fruit'], ['banana', 'fruit'], ['grapes', 'fruit'], ['red', 'color'], ['blue', 'color'], ['black', 'color']],
    result = _(data)
        .groupBy(1)
        .map((array, group) => ({ group, value: _.map(array, 0) }))
        .sortBy('group')
        .value();

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

答案 2 :(得分:1)

以下是我在对您的问题的评论中描述的一种方法:

  1. 您遍历所有元素,并创建一个空白数组
  2. 在新创建的数组中,找到与group值匹配的对象
  3. 如果找到,则扩展元素
  4. 如果找不到,则创建它

    abc.reduce((arr, input) => {
      const index = arr.findIndex(i => i.group === input[0])
    
      return [
        ...(index > -1
          ? [
            ...arr.slice(0, index),
            {
              group: input[0],
              value: [
                ...arr[index].value,
                input[1]
              ]
            },
            ...arr.slice(index + 1)
          ] : [
            ...arr,
            {
              group: input[0],
              value: [ input[1] ]
            }
          ])
      ]
    }, [])
    

答案 3 :(得分:1)

以下是使用ES6 Map作为中间数据结构的方法:

var abc = [['apple', 'fruit'],['banana', 'fruit'],['grapes', 'fruit'],['red', 'color'],['blue', 'color'],['black', 'color']];
    
const groups = new Map(abc.map(a =>[a[1], []]));
abc.forEach(a => groups.get(a[1]).push(a[0]));
const result = Array.from(groups, ([group, values]) =>  ({group, values}));

console.log(result);

答案 4 :(得分:0)

您可以构建一个hashtavle来查找重复的描述符:

 const result = [], hash = {};

 for(const [value, group] of abc) {
  if(hash[group]) {
   hash[group].push(value);
  } else {
   result.push({ group, value: (hash[group] = [value]), });
  }
}

答案 5 :(得分:0)

使用单个reduce

var abc = [
  ['apple', 'fruit'],
  ['banana', 'fruit'],
  ['grapes', 'fruit'],
  ['red', 'color'],
  ['blue', 'color'],
  ['black', 'color']
]

var r = abc.reduce((prev, curr) => {
  if(prev.findIndex(p => p.group === curr[1]) === -1) {
    prev = prev.concat({group: curr[1], value: []})
  }
  let idx = prev.findIndex(p => p.group === curr[1])
  prev[idx].value.push( curr[0] )
  return prev;
}, [])

console.log(r)