【问题标题】:Restructure Javascript Object by grouping and Cartesian product通过分组和笛卡尔积重构Javascript对象
【发布时间】:2019-01-24 09:53:18
【问题描述】:

我有一些从 api 返回的原始 javascript,如下所示:

     {"Values":
    [
 {
        "fieldValue": 1,
        "fieldName": "A"
      },
      {
        "fieldValue": 2,
        "fieldName": "A"
      },
      {
        "fieldValue": "FOO",
        "fieldName": "B"
      },
      {
        "fieldValue": "BAR",
        "fieldName": "B"
      }
    ]
}

我想以一种需要对属性进行分组、将属性转换为值和笛卡尔连接的方式对其进行重组,从而生成如下所示的对象数组:

[{"A":1,"B":"FOO"},{"A":2,B:"FOO"},{"A":1,"B":"BAR"},{"A":2,"B":"BAR"}]

我一直在查看 loDash 和 loDash.product 库,它们很有帮助,但并没有让我满意。 _groupby 给了我一个数组对象而不是一个对象数组:

{object:
[fieldName:"A",fieldValue:1],[fieldName:"A",fieldValue:2],[fieldName:"B",fieldValue:1],[fieldName:"B",fieldValue:2]
}

【问题讨论】:

    标签: javascript arrays json lodash


    【解决方案1】:

    首先,使用给定数据创建一个对象并收集键及其值。

    {
        A: [1, 2],
        C: ["FOO", "BAR"]
    }
    

    然后,得到这个对象的笛卡尔积。

    如果带有对象的数组再次调用getCartesian,则函数getCartesian 会分离所有键/值对并通过迭代值来构建新的笛卡尔积,并构建新对象。

    这也适用于嵌套对象。

    该算法非常简单,因为它接受任何具有值的属性,而不仅仅是数组或对象,并保留该值并迭代所有其他属性,即数组或对象。该算法保留内部结构,仅将原始值作为给定结构的结果值。

    一开始,它接受一个对象/数组,获取所有条目并使用一个包含空对象的数组来迭代它们。

    空数组temp 是新结果。

    为了创建新元素,累加器r 被迭代并收集新值。这是制作笛卡尔积的第一级的部分。

    对于更深的层次,检查一个值以及“如果一个对象”,然后进行递归调用,并将新结果作为实际键。

    function getCartesian(object) {
        return Object.entries(object).reduce((r, [k, v]) => {
            var temp = [];
            r.forEach(s =>
                (Array.isArray(v) ? v : [v]).forEach(w =>
                    (w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
                        temp.push(Object.assign({}, s, { [k]: x }))
                    )
                )
            );
            return temp;
        }, [{}]);
    }
    
    var data = { Values: [{ fieldValue: 1, fieldName: "A" }, { fieldValue: 2, fieldName: "A" }, { fieldValue: "FOO", fieldName: "C" }, { fieldValue: "BAR", fieldName: "C" }] },
        temp = data.Values.reduce((r, { fieldName, fieldValue }) => {
            (r[fieldName] = r[fieldName] || []).push(fieldValue);
            return r;
        }, {}),
        cartesian = getCartesian(temp);
    
    console.log(cartesian);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      猜你喜欢
      • 2013-09-28
      • 2014-12-29
      • 1970-01-01
      • 2018-02-17
      • 2016-01-19
      • 1970-01-01
      • 2016-11-22
      • 2012-02-24
      • 2011-09-18
      相关资源
      最近更新 更多