如何使用Array类型将选定的Object属性提取到新创建的属性?

时间:2017-02-06 20:49:16

标签: javascript ecmascript-6 lodash

我有一个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
}]

如何使用LODASH将此类集合转换为以下结构(添加值属性作为值来自'值'和' value2':

的值数组
let abc = [{
        categoryId: 1,
        categoryName: 'Test',
        programId: 112,
        programName: 'Program Test',
        values: [5050,1000]
    },
    ...
    ]

4 个答案:

答案 0 :(得分:3)

您需要使用基本的地图操作来转换数组。 使用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]
    };
});

但我希望通过使用 Array.prototype.map 函数来跟踪"You Dont Need Lodash"趋势

答案 1 :(得分:2)

如果你寻求一些灵活性,并且不知道你的对象可能具有的所有属性,但想要将任何value*属性值合并在一起,那么你可以在这个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; }

如果值的顺序很重要,那么在最后sort之前的链中注入.map()

Lodash

使用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)
        }))
    );
});

答案 2 :(得分:1)

您可以使用_.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
    );
});

答案 3 :(得分:0)

我将所有以"value"开头的属性加在一起,以防万一。



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>
&#13;
&#13;
&#13;