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

Need help using lodash to reform an array with new structure

我有一个从 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 的新手,我已经花了好几个小时去探索几个没有解决的问题。我意识到是时候求助于专家了。关于如何获得上面显示的最终结果的任何建议?

感谢您的帮助!

您可以使用 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"
            }
        ]
    }
]

可能有更简单的方法来收集属性,但只有3个键,硬编码也不会太麻烦。

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

基本上,而不是这个:

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

你可以简单地做

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

您可以遍历您的数据,在对象中构建所需的结构以便 InsightId 轻松查找,然后使用 _.values 将其转换为您想要的平面数组.

    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>