groupBy和值作为键 [英] groupBy and value as key

查看:76
本文介绍了groupBy和值作为键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下数据:

var groups = {
  0: { 'GroupID': 1, 'AttributeID': 'Agitator', 'Value': 'No' },
  1: { 'GroupID': 1, 'AttributeID': 'ATG', 'Value': 'Custodian' },
  2: { 'GroupID': 1, 'AttributeID': 'Heating Coil', 'Value': 'Mild Steel' },
  3: { 'GroupID': 2, 'AttributeID': 'Agitator', 'Value': 'Yes' },
  4: { 'GroupID': 2, 'AttributeID': 'ATG', 'Value': 'Non Custodian' },
  5: { 'GroupID': 2, 'AttributeID': 'Heating Coil', 'Value': 'Mild Steel' },
};

我想按GroupID对数据进行分组,并将其中一个值用作另一个值的键.预期结果如下.这可以实现吗?

I would like to group the data by GroupID and use one of the value as key for another value. The expected outcome will be as following. Is this achievable?

var data = {
  0: { 'GroupID': 1, 'Agitator': 'No', 'ATG': 'Custodian', 'Heating Coil': 'Mild Steel' },
  1: { 'GroupID': 2, 'Agitator': 'Yes', 'ATG': 'Non Custodian', 'Heating Coil': 'Mild Steel' }
};

到目前为止,我尝试过的操作如下.我不知道如何使一个值成为另一个值的键.

So far what I have tried is as below. I have no idea how to make one of value as key for another value.

_.chain(groups).groupBy('GroupID').map((value, key) => {
    return {
      GroupID: key,
      AttributeID: _.map(value, 'AttributeID'),
      Value: _.map(value, 'Value')
    }
}).value();

结果如下所示.

var data = {
      0: { 'GroupID': 1, 'AttributeID': ['Agitator', 'ATG', 'Heating Coil'], 'Value': ['No', 'Custodian', 'Mild Steel'] },
      1: { 'GroupID': 2, 'AttributeID': ['Agitator', 'ATG', 'Heating Coil'], 'Value': ['Yes', 'Non Custodian', 'Mild Steel'] }
    };

感谢任何帮助.

推荐答案

您已经非常接近解决自己的问题了.做得好!让我们将其分解成几部分,看看缺少了什么.

You got very close to solving your own question. Well done! Let's break this into parts and see what's missing.

您正确地确定了 _.groupBy 是收集具有相同 GroupID 的对象所需要的.

You correctly identified that _.groupBy is what you need in order to collect objects with the same GroupID.

var grouped = _.groupBy(groups, 'GroupID');
// { '1':
//    [ { GroupID: 1, AttributeID: 'Agitator', Value: 'No' },
//      { GroupID: 1, AttributeID: 'ATG', Value: 'Custodian' },
//      { GroupID: 1, AttributeID: 'Heating Coil', Value: 'Mild Steel' } ],
//   '2':
//    [ { GroupID: 2, AttributeID: 'Agitator', Value: 'Yes' },
//      { GroupID: 2, AttributeID: 'ATG', Value: 'Non Custodian' },
//      { GroupID: 2, AttributeID: 'Heating Coil', Value: 'Mild Steel' } ] }

您还正确地将 _.map 标识为可让您跨对象数组收集特定属性值的函数.

You also correctly identified _.map as the function that lets you collect the values of a particular property across an array of objects.

var firstGroupAttributes = _.map(grouped['1'], 'AttributeID');
// [ 'Agitator', 'ATG', 'Heating Coil' ]

您编写的用于为每个组构造最终对象的函数为第一组产生了以下对象:

The function you wrote to construct the final object for each group produced the following object for the first group:

{
    'GroupID': 1,
    'AttributeID': ['Agitator', 'ATG', 'Heating Coil'],
    'Value': ['No', 'Custodian', 'Mild Steel']
}

通常, AttributeID Value 属性具有相同的顺序,因此 Value 数组的第一个元素对应于 AttributeID 数组,第二个到第二个,依此类推.下划线具有一个称为 _.object 1 的函数.,它可以接受这样一对数组并返回一个对象,其中第一个数组的每个元素命名一个属性,第二个数组的相应元素提供其值:

Conveniently, the AttributeID and Value properties have the same order, so the first element of the Value array corresponds to the first element of the AttributeID array, the second to the second, and so forth. Underscore has a function called _.object1, which can take such a pair of arrays and return an object where each element of the first array names a property and the corresponding element of the second array provides its value:

_.object(['Agitator', 'ATG'], ['No', 'Custodian']);
// { Agitator: 'No',
//   ATG: 'Custodian', }

照顾好属性及其值之后,现在我们只需向对象添加 GroupID .有几种类似但略有不同的功能可用于此目的,例如 _.extend _.defaults :

Having taken care of the attributes and their values, now we just need to add the GroupID to the object. There are several similar but slightly different functions that work for this purpose, such as _.extend and _.defaults:

_.extend({ a: 1 }, { b: 2 });
// { a: 1, b: 2 }

将这些成分放在一起,我们在 grouped 上映射的函数可能看起来像这样:

Putting these ingredients together, the function that we map over grouped could look something like this:

function mergeGroup(value, key) {
    var attributes = _.map(value, 'AttributeID');
    var values = _.map(value, 'Value');
    return _.chain(attributes).object(values).extend({ GroupID: key }).value();
}

如果您像以前那样使用 _.map ,则会得到包含最终对象的数组.

If you use _.map, as you did, you get an array with the final objects.

var data = _.chain(groups).groupBy('GroupID').map(mergeGroup).value();
// [ { Agitator: 'No',
//     ATG: 'Custodian',
//     'Heating Coil': 'Mild Steel',
//     GroupID: '1' },
//   { Agitator: 'Yes',
//     ATG: 'Non Custodian',
//     'Heating Coil': 'Mild Steel',
//     GroupID: '2' } ]

或者,您可以使用 _.mapObject 2 产生一个对象,其中每个键与 GroupID :

Alternatively, you could use _.mapObject2 to produce an object where each key is the same as the GroupID:

var data = _.chain(groups).groupBy('GroupID').mapObject(mergeGroup).value();
// { '1':
//    { Agitator: 'No',
//      ATG: 'Custodian',
//      'Heating Coil': 'Mild Steel',
//      GroupID: '1' },
//   '2':
//    { Agitator: 'Yes',
//      ATG: 'Non Custodian',
//      'Heating Coil': 'Mild Steel',
//      GroupID: '2' } }


1 Lodash最初从Underscore继承了 _.object ,但是他们添加了一个名为 _.zipObject 的别名,他们决定在版本4中从其界面中删除原始名称 _.object .因此,如果使用Lodash,则必须调用 _.zipObject .下划线的 _.object 也可以使用成对的数组而不是成对的数组.在Lodash 4中,您可以使用 _.fromPairs 代替.


1 Lodash originally inherited _.object from Underscore, but they added an alias called _.zipObject and in version 4, they decided to remove the original name _.object from their interface. So you'd have to call _.zipObject if using Lodash. Underscore's _.object can also work with an array of pairs instead of a pair of arrays; in Lodash 4, you'd use _.fromPairs for that instead.

2 _.mapValues .

这篇关于groupBy和值作为键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆