[英]Transform array of objects using lodash or ramda
这是查询数据库后获得的数据结构。
[
{ name: 'xx1', date: '2017-09-03', value: 49 },
{ name: 'xx2', date: '2017-10-23', value: 67 },
{ name: 'xx2', date: '2017-12-01', value: 70 },
...
]
我想将其转换为:
[
{ name: 'xx1', data: { '2017-09-03': 49 } },
{ name: 'xx2', data: { '2017-10-23': 67, '2017-12-01': 70 } },
...
]
为了使用react-chartkick构建图表,需要该数据结构。
谁能给我建议解决这个问题? (尤其是lodash或ramda)
我将基于reduce
和find
(ES6)方法使用以下方法:
const data = [
{ name: 'xx1', date: '2017-09-03', value: 49 },
{ name: 'xx2', date: '2017-10-23', value: 67 },
{ name: 'xx2', date: '2017-12-01', value: 70 }
];
const result = data.reduce((acc, item) => {
const found = acc.find(a => a.name === item.name);
if (found) {
found.data[item.date] = item.value;
} else {
acc.push({
name: item.name,
data: {
[item.date]: item.value
}
});
}
return acc;
}, []);
您可以使用Array#reduce()
累积对象并返回其Object.values()
:
const data = [ { name: 'xx1', date: '2017-09-03', value: 49 }, { name: 'xx2', date: '2017-10-23', value: 67 }, { name: 'xx2', date: '2017-12-01', value: 70 } ] const map = data.reduce((acc, { name, date, value }) => { if (!(name in acc)) { acc[name] = { name, data: {} } } acc[name].data[date] = value return acc }, {}) const result = Object.values(map) console.log(result)
这种方法避免使用Array#find()
,它的时间复杂度为O(n),并且name in acc
使用name in acc
来检查是否存在,并且使用acc[name]
进行访问,这两者都是O(1)的时间复杂度,因此该方法为O(n ) 总体。
相反, 另一个答案是总体的O(n 2 )时间复杂度。
对于使用lodash的解决方案,可以使用其_.map
, _.groupBy
和_.merge
方法来完成此任务。
我发现使用_.chain
样式更容易_.chain
,但是您可以根据需要轻松地将其转换为一组普通的嵌套调用。
const data = [ { name: 'xx1', date: '2017-09-03', value: 49 }, { name: 'xx2', date: '2017-10-23', value: 67 }, { name: 'xx2', date: '2017-12-01', value: 70 }, ] const result = _.chain(data) .map(val => ({name: val.name, data: {[val.date]: val.value}})) // convert objects to desired format .groupBy("name") // group objects by name .map(v => _.merge(...v)) // merge objects in each group .value(); // done! console.log(result);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
R.reduceBy
的R.reduceBy
或R.groupBy
可以在这里为您提供帮助。 在下面的示例中, R.reduceBy
通过name
属性对数组中的对象进行分组,然后通过使用R.assoc
建立新对象来组合分组的元素。 R.toPairs
, R.map
和R.zipObj
的其余组合将结果转换为所需的形状。
const fn = R.pipe( R.reduceBy((res, {date, value}) => R.assoc(date, value, res), {}, R.prop('name')), R.toPairs, R.map(R.zipObj(['name', 'data'])) ) const data = [ { name: 'xx1', date: '2017-09-03', value: 49 }, { name: 'xx2', date: '2017-10-23', value: 67 }, { name: 'xx2', date: '2017-12-01', value: 70 } ] console.log(fn(data))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.