我从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]
}
答案 0 :(得分:3)
首先,使用给定的数据创建一个对象,并收集键及其值。
{
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; }