将多维对象数组简化为单个对象数组

时间:2019-03-12 15:52:11

标签: javascript arrays object reduce transpose

我有这个多维的对象数组-

<html>
<head>
<style>


h1 {
  color: #FF0000;
}

h1:first-letter:hover {
 
  color: #000;
  transform: scaleX(-1);
  transition: all 3s ease-in-out 0s;
  
  }

</style>
</head>

<body>

<h1>RISVOLTO</h1>


</body>
</html>

我需要将其转换为该数组-

const initialArray = [
  {
   name: 'aaa', 
   value:[{id:1, data:1}, {id:2, data:2}, {id:3, data:3}]
  },
  {
   name: 'bbb', 
   value:[{id:1, data:4}, {id:2, data:5}, {id:3, data:6}]
  },
  {
   name: 'ccc', 
   value:[{id:1, data:7}, {id:2, data:8}, {id:3, data:7}]
  },
  {
   name: 'ddd', 
   value:[{id:1, data:2}, {id:2, data:1}, {id:3, data:1}]
  }
]

我目前的解决方案是

const finalArray = [
  {
    id: 1, aaa: 1, bbb: 4, ccc: 7, ddd: 2
  },
  {
    id: 2, aaa: 2, bbb: 5, ccc: 8, ddd: 1
  },
  {
    id: 3, aaa: 3, bbb: 6, ccc: 7, ddd: 1
  }
]

有没有更好,更优雅的方法来做到这一点?我正在尝试通过减少遍历每个数组的次数以及更少的代码和更高的可读性来实现这一点。如您所见,每次迭代过程中的some和find都会增加迭代次数。有什么办法可以减少它?

3 个答案:

答案 0 :(得分:5)

function tranform(array) {
  const obj = {}
  
  array.forEach(({name, value}) => (value || []).forEach(({id, data}) => obj[id] = { id, ...obj[id], [name]: data } ))
  
  return Object.values(obj)
}

const initialArray = [
  {
   name: 'aaa', 
   value:[{id:1, data:1}, {id:2, data:2}, {id:3, data:3}]
  },
  {
   name: 'bbb', 
   value:[{id:1, data:4}, {id:2, data:5}, {id:3, data:6}]
  },
  {
   name: 'ccc', 
   value:[{id:1, data:7}, {id:2, data:8}, {id:3, data:7}]
  },
  {
   name: 'ddd', 
   value:[{id:1, data:2}, {id:2, data:1}, {id:3, data:1}]
  }
]

console.log(tranform(initialArray))

答案 1 :(得分:1)

您可以使用Map来收集具有相同id的对象。

var initialArray = [{ name: 'aaa', value: [{ id: 1, data: 1 }, { id: 2, data: 2 }, { id: 3, data: 3 }] }, { name: 'bbb', value: [{ id: 1, data: 4 }, { id: 2, data: 5 }, { id: 3, data: 6 }] }, { name: 'ccc', value: [{ id: 1, data: 7 }, { id: 2, data: 8 }, { id: 3, data: 7 }] }, { name: 'ddd', value: [{ id: 1, data: 2 }, { id: 2, data: 1 }, { id: 3, data: 1 }] }],
    result = Array.from(initialArray
        .reduce(
            (m, { name, value }) => value.reduce(
                (n, { id, data }) => n.set(id, Object.assign(
                    n.get(id) || { id },
                    { [name]: data }
                )),
                m
            ),
            new Map
        )
        .values()
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)

这对我来说似乎是可读的(请注意,我投票决定关闭您的问题,因为“主要基于意见”)

initial = [{ 
  name : "aaa",
  value : [
    { id : 1, data : 1 },
    { id : 2, data : 2 },
    { id : 3, data : 3 }
  ]
}, {
  name : "bbb",
  value : [
    { id : 1, data : 4 },
    { id : 2, data : 5 },
    { id : 3, data : 6 }
  ]
}, {
  name : "ccc",
  value : [
    { id : 1, data : 7 },
    { id : 2, data : 8 },
    { id : 3, data : 7 }
  ]
}, {
  name : "ddd",
  value : [
    { id : 1, data : 2 },
    { id : 2, data : 1 },
    { id : 3, data : 1 }
  ]
}];

map = {};
final = [];

for (i = 0; i < initial.length; i++) {
  x = initial[i];
  for (j = 0; j < x.value.length; j++) {
    y = x.value[j];
    if (!map[y.id]) map[y.id] = { id: y.id };
    map[y.id][x.name] = y.data;
  }
}

for (k in map) {
  final.push(map[k]);
}

for (i = 0; i < final.length; i++) {
  console.log(JSON.stringify(final[i]));
}