I have an JS collection (array of objects with few properties).
我有一个JS集合(具有很少属性的对象数组)。
let xyz = [{
categoryId: 1,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
},
{
categoryId: 2,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
},
{
categoryId: 3,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
}]
How to transform such collection using LODASH to the following structure (added values property as an array of values coming from 'value' and 'value2':
如何使用LODASH将此类集合转换为以下结构(添加值属性作为来自“value”和“value2”的值数组):
let abc = [{
categoryId: 1,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
values: [5050,1000]
},
...
]
4 个解决方案
#1
3
You need to transform your array using basic map operation. Using lodash:
您需要使用基本的映射操作来转换数组。使用lodash:
let abc = _.map(xyz, function(el) {
return {
categoryId: el.categoryId,
categoryName: el.categoryName,
programId: el.programId,
programName: el.programName,
values: [el.value, el.value2]
};
});
But I would rather follow "You Dont Need Lodash" trend here by using Array.prototype.map function
但是我更愿意使用Array.prototype跟随“您不需要Lodash”的趋势。map函数
#2
2
If you look for some flexibility, and don't know all the properties your objects might have, but want to merge any value*
property values together, then you could maybe find inspiration in this ES6 code:
如果您寻找一些灵活性,并且不知道您的对象可能拥有的所有属性,但是希望将任何值*属性值合并在一起,那么您可能会在这个ES6代码中找到灵感:
let res = xyz.map( o => Object.assign({},
...Object.keys(o).map(key => !key.test(/^value\d*$/) && ({ [key]: o[key]})),
{ values: Object.keys(o).filter(key => key.test(/^value\d*$/)).map(key => o[key]) }
));
let xyz = [{
categoryId: 1,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
},
{
categoryId: 2,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
},
{
categoryId: 3,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
}];
let res = xyz.map( o => Object.assign({},
...Object.keys(o).map(key => !/^value\d*$/.test(key) && ({ [key]: o[key]})),
{ values: Object.keys(o).filter(key => /^value\d*$/.test(key)).map(key => o[key]) }
));
console.log(res);
.as-console-wrapper { max-height: 100% !important; top: 0; }
If the order of the values is important, then inject a sort
in the chain, just before the final .map()
.
如果值的顺序很重要,那么在最后的.map()之前在链中注入排序。
Lodash
With lodash it could look like this (sticking to ES5 code this time):
有了lodash,它看起来就像这样(这一次坚持ES5代码):
var res = _.map(xyz, function (o) {
return _.set(
_.omitBy(o, function (v, key) { return /^value\d*$/.test(key) }),
'values',
_.values(_.pickBy(o, function (v, key) {
return /^value\d*$/.test(key)
}))
);
});
#3
1
you can do it with _.merge
可以用_.merge来实现
var res = _.map(xyz, function(item) {
return _.merge(
{}, // to avoid xyz mutations
_.omit(item, ['value', 'value2']), // remove useless keys
{values: _.at(item, ['value', 'value2'])} // get needed values
);
});
#4
0
I added together all the properties that start with "value"
, just in case.
我将所有以“值”开头的属性加在一起,以防万一。
let xyz = [{
categoryId: 1,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
},
{
categoryId: 2,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
},
{
categoryId: 3,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
}]
let abc = _.map(xyz, function (obj) {
var valuesKeys = _.filter(_.keys(obj), function (key) {
return key.indexOf('value') === 0;
});
let result = _.omit(obj, valuesKeys);
result.values = _.reduce(_.values(_.pick(obj, valuesKeys)), _.add);
return result;
});
console.log(abc);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
#1
3
You need to transform your array using basic map operation. Using lodash:
您需要使用基本的映射操作来转换数组。使用lodash:
let abc = _.map(xyz, function(el) {
return {
categoryId: el.categoryId,
categoryName: el.categoryName,
programId: el.programId,
programName: el.programName,
values: [el.value, el.value2]
};
});
But I would rather follow "You Dont Need Lodash" trend here by using Array.prototype.map function
但是我更愿意使用Array.prototype跟随“您不需要Lodash”的趋势。map函数
#2
2
If you look for some flexibility, and don't know all the properties your objects might have, but want to merge any value*
property values together, then you could maybe find inspiration in this ES6 code:
如果您寻找一些灵活性,并且不知道您的对象可能拥有的所有属性,但是希望将任何值*属性值合并在一起,那么您可能会在这个ES6代码中找到灵感:
let res = xyz.map( o => Object.assign({},
...Object.keys(o).map(key => !key.test(/^value\d*$/) && ({ [key]: o[key]})),
{ values: Object.keys(o).filter(key => key.test(/^value\d*$/)).map(key => o[key]) }
));
let xyz = [{
categoryId: 1,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
},
{
categoryId: 2,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
},
{
categoryId: 3,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
}];
let res = xyz.map( o => Object.assign({},
...Object.keys(o).map(key => !/^value\d*$/.test(key) && ({ [key]: o[key]})),
{ values: Object.keys(o).filter(key => /^value\d*$/.test(key)).map(key => o[key]) }
));
console.log(res);
.as-console-wrapper { max-height: 100% !important; top: 0; }
If the order of the values is important, then inject a sort
in the chain, just before the final .map()
.
如果值的顺序很重要,那么在最后的.map()之前在链中注入排序。
Lodash
With lodash it could look like this (sticking to ES5 code this time):
有了lodash,它看起来就像这样(这一次坚持ES5代码):
var res = _.map(xyz, function (o) {
return _.set(
_.omitBy(o, function (v, key) { return /^value\d*$/.test(key) }),
'values',
_.values(_.pickBy(o, function (v, key) {
return /^value\d*$/.test(key)
}))
);
});
#3
1
you can do it with _.merge
可以用_.merge来实现
var res = _.map(xyz, function(item) {
return _.merge(
{}, // to avoid xyz mutations
_.omit(item, ['value', 'value2']), // remove useless keys
{values: _.at(item, ['value', 'value2'])} // get needed values
);
});
#4
0
I added together all the properties that start with "value"
, just in case.
我将所有以“值”开头的属性加在一起,以防万一。
let xyz = [{
categoryId: 1,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
},
{
categoryId: 2,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
},
{
categoryId: 3,
categoryName: 'Test',
programId: 112,
programName: 'Program Test',
value: 5050,
value2: 1000
}]
let abc = _.map(xyz, function (obj) {
var valuesKeys = _.filter(_.keys(obj), function (key) {
return key.indexOf('value') === 0;
});
let result = _.omit(obj, valuesKeys);
result.values = _.reduce(_.values(_.pick(obj, valuesKeys)), _.add);
return result;
});
console.log(abc);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>