通过分组和笛卡尔积重构Javascript对象
我从api返回了一些原始javascript,如下所示:通过分组和笛卡尔积重构Javascript对象,javascript,arrays,json,lodash,Javascript,Arrays,Json,Lodash,我从api返回了一些原始javascript,如下所示: {"Values": [ { "fieldValue": 1, "fieldName": "A" }, { "fieldValue": 2, "fieldName": "A" }, { "fieldValue": "FOO", "fieldName": "B" },
{"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"}]
我想以一种需要对属性进行分组、将属性转换为值以及笛卡尔连接的方式对其进行重新构造,该笛卡尔连接将生成如下所示的对象数组:
{"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]
}
首先,使用给定的数据创建一个对象,并收集键及其值
{
A: [1, 2],
C: ["FOO", "BAR"]
}
然后,得到这个物体的笛卡尔积
如果带有对象的数组再次调用getCartesian
并构建新对象,则函数getCartesian
将分离所有键/值对,并通过迭代这些值来构建新的笛卡尔乘积
这也适用于嵌套对象
该算法非常简单,因为它接受任何具有值的属性,而不仅仅是数组或对象,并保留该值并迭代所有其他属性,即数组或对象。该算法保留了内部结构,只取原始值作为给定结构的结果值
在开始时,它获取一个对象/数组,获取所有条目,并使用带有空对象的数组对它们进行迭代
新结果为空数组temp
为了创建新元素,累加器r
被迭代并收集新值。这是制作笛卡尔积的第一级的部分
对于更深层次,检查一个值以及“if a object”,然后进行递归调用,并为实际键获取新结果
函数getCartesian(对象){
返回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=>
临时推送(对象赋值({},s,{[k]:x}))
)
)
);
返回温度;
}, [{}]);
}
变量数据={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]| |[])。推送(fieldValue);
返回r;
}, {}),
笛卡尔=getCartesian(温度);
console.log(笛卡尔)代码>
。作为控制台包装{最大高度:100%!重要;顶部:0;}