需要帮助使用lodash来改造具有新结构的阵列

时间:2015-03-14 23:54:00

标签: javascript arrays grouping lodash

我有一个从我想要改造成具有分组对象子数组的数组的API返回的示例数据。来自API的原始数据如下所示:

[
    {
        "InsightId": 314,
        "Classification": "Advantage",
        "AttributeId": 14958,
        "InsightAttribute": "Implementation speed",
        "AttributeType": "Product Criterion"
    },
    {
        "InsightId": 314,
        "Classification": "Advantage",
        "AttributeId": 14976,
        "InsightAttribute": "Understanding your needs",
        "AttributeType": "Sales Criterion"
    },
    {
        "InsightId": 315,
        "Classification": "Disadvantage",
        "AttributeId": 17691,
        "InsightAttribute": "Poor alignment with needs",
        "AttributeType": "Product Criterion"
    }
]

我想通过InsightId进行分组,并从三个属性中创建一个对象:AttributeId,InsightAttribute,AttributeType。

让最终的数组采用以下形式:

[
    {
        "InsightId": 314,
        "Classification": "Advantage",
        "Attributes" : [
            {
                "AttributeId": 14958,
                "InsightAttribute": "Implementation speed",
                "AttributeType": "Product Criterion"
            },

            {
                AttributeId": 14976,
                "InsightAttribute": "Understanding your needs",
                "AttributeType": "Sales Criterion"
            }
        ]
    },
    {
        "InsightId": 315,
        "Classification": "Disadvantage",
        "Attributes" : [
            {
                "AttributeId": 17691,
                "InsightAttribute": "Poor alignment with needs",
                "AttributeType": "Product Criterion"
            }
        ]   
    }
]

我是Lodash的新手,而且我已经花了好几个小时去了几个尚未解决的兔子洞。我已经意识到是时候转向专家了。关于如何获得上述结果的任何建议?

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

你可以使用reduce()来循环并建立一个新的响应:

  _.values( _.reduce([{
    "InsightId": 314,
    "Classification": "Advantage",
    "AttributeId": 14958,
    "InsightAttribute": "Implementation speed",
    "AttributeType": "Product Criterion"
  }, {
    "InsightId": 314,
    "Classification": "Advantage",
    "AttributeId": 14976,
    "InsightAttribute": "Understanding your needs",
    "AttributeType": "Sales Criterion"
  }, {
    "InsightId": 315,
    "Classification": "Disadvantage",
    "AttributeId": 17691,
    "InsightAttribute": "Poor alignment with needs",
    "AttributeType": "Product Criterion"
  }], function(a, b) {

    // create a new array for common items under InsightId:
    var temp=a[b.InsightId] = a[b.InsightId] || {
        InsightId: b.InsightId,
        Classification: b.Classification,
        Attributes: []
    };

    // push current attribs into collection under InsightId:
    temp.Attributes.push({
        AttributeId: b.AttributeId,
        InsightAttribute: b.InsightAttribute,
        AttributeType: b.AttributeType
    });
    return a;
  }, {}));

回馈:

[
    {
        "InsightId": 314,
        "Classification": "Advantage",
        "Attributes": [
            {
                "AttributeId": 14958,
                "InsightAttribute": "Implementation speed",
                "AttributeType": "Product Criterion"
            },
            {
                "AttributeId": 14976,
                "InsightAttribute": "Understanding your needs",
                "AttributeType": "Sales Criterion"
            }
        ]
    },
    {
        "InsightId": 315,
        "Classification": "Disadvantage",
        "Attributes": [
            {
                "AttributeId": 17691,
                "InsightAttribute": "Poor alignment with needs",
                "AttributeType": "Product Criterion"
            }
        ]
    }
]

可能有一种稍微简单的方法来收集attribs,但只有3个键,硬编码不会太麻烦。

答案 1 :(得分:0)

这里lodash最有用的部分是pick,它允许你有选择地按名称切出一些对象的属性。

基本上,而不是:

obj1 = {
  name: obj2.name
  age: obj2.age
  size: obj2.size
}

你可以简单地做

obj1 = _.pick(obj1, 'name', 'age', 'size')

您可以迭代数据,在对象中构建所需的结构,以便InsightId轻松查找,然后将其转换为之后使用_.values的平面数组。< / p>

    data = [
        {
            "InsightId": 314,
            "Classification": "Advantage",
            "AttributeId": 14958,
            "InsightAttribute": "Implementation speed",
            "AttributeType": "Product Criterion"
        },
        {
            "InsightId": 314,
            "Classification": "Advantage",
            "AttributeId": 14976,
            "InsightAttribute": "Understanding your needs",
            "AttributeType": "Sales Criterion"
        },
        {
            "InsightId": 315,
            "Classification": "Disadvantage",
            "AttributeId": 17691,
            "InsightAttribute": "Poor alignment with needs",
            "AttributeType": "Product Criterion"
        }
    ]
    
    hash = {}
    
    data.forEach(function (r) {
      if (!hash[r.InsightId])
        hash[r.InsightId] = _.merge(
          _.pick(r, 'InsightId', 'Classification'), {Attributes: []}
        );

      hash[r.InsightId].Attributes.push(_.pick(r, "AttributeId", "InsightAttribute", "AttributeType"))
    });


    output = _.values(hash);
    

    console.log(output);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.js"></script>