如何使用数组递归 split/flatten 一个对象
How to recursively split/flatten an object with Arrays
我正在尝试递归拆分某种对象,如果它具有一些值作为数组。
- 如果没有值是数组,它应该 return 对象原样。
- 如果有一个值是空数组,它应该 return 对象原样,但用空字符串替换该数组值
- 如果有多个数组值,应该return 扁平化分割对象。例如,如果有一个带有数组的对象,例如 :
{
"wq": "e2201b13-aa03-4044-b4e3-1ecb25ef5083",
"we": "2019-08-19T00:00:00",
"er": "2019-09-18T00:00:00",
"rt": "PAID",
"ty": "300.00",
"yu": "27.27",
"ui": "272.73",
"io": "0",
"op": "300.00",
"pa": "8df30d22-5af3-4d61-a420-566ccdad8cdf",
"as": "AUD",
"sd": false,
"df": false,
"fg": "2019-12-04T19:57:48",
"gh": "2019-09-16T00:00:00",
"hj": "0",
"jk": [
"6c9809af-269b-4b86-8b07-78c83a12bd18",
"6c9809af-269b-4b86-8b07-78c83a12bd19"
],
"lk": [
'112',
'111',
],
"zx": null,
"xc": "",
"vb": []
}
它应该 return 一个包含 4 个对象的数组,用于这些对象的所有排列。其中 lk、jk 和 vb 的值是字符串。 vb 永远是空白的,因为它是一个空白对象。如果在源对象中 vb 是这样的 '' 即空白字符串,那将是一样的。
4 个对象,因为有 2 个数组,每个数组有 2 个对象。 2^2 = 4。例如,如果 vb 也有 2 个对象,则将有 2^3=8 个对象,所有其他键都相同,但提到的 3 个键为字符串。
- 数组中的值未知。所以,它可以是任意数量的od值,范围从0-n
- 源对象中可以是数组的键未知。所以需要递归遍历。
- 源对象中的值也可以是null或{}对象,可以忽略。
到目前为止,我已经编写了这样的入门程序:
const result = [];
const reserve = {};
Object.keys(source).forEach((key) => {
if (source[key] instanceof Object) {
// const isArr = Array.isArray(source[key]);
source[key].forEach((element) => {
result.push({
...source,
[key]: element
});
});
} else {
reserve[key] = source[key]
}
})
console.log(result)
// console.log(reserve)
// console.log(result.map(i => Object.assign({}, i, reserve)))
它在某种程度上给了我想要的输出,但仍然需要工作。欢迎任何推荐和建议。
假设您想要获得笛卡尔积并将空数组保留为单个值,您可以关注此数据。
如果包含对象的数组再次调用 getCartesian
并构建新对象,您可以采用递归函数分离所有 key/value 对并通过迭代值构建新的笛卡尔积。
function getCartesian(object) {
return Object.entries(object).reduce((r, [k, v]) => {
var temp = [];
r.forEach(s =>
(Array.isArray(v) && v.length ? v : [v]).forEach(w =>
(w && typeof w === 'object' && (!Array.isArray(w) || w.length) ? getCartesian(w) : [w]).forEach(x =>
temp.push(Object.assign({}, s, { [k]: x }))
)
)
);
return temp;
}, [{}]);
}
var data = { wq: "e2201b13-aa03-4044-b4e3-1ecb25ef5083", we: "2019-08-19T00:00:00", er: "2019-09-18T00:00:00", rt: "PAID", ty: "300.00", yu: "27.27", ui: "272.73", io: "0", op: "300.00", pa: "8df30d22-5af3-4d61-a420-566ccdad8cdf", as: "AUD", sd: false, df: false, fg: "2019-12-04T19:57:48", gh: "2019-09-16T00:00:00", hj: "0", jk: ["6c9809af-269b-4b86-8b07-78c83a12bd18", "6c9809af-269b-4b86-8b07-78c83a12bd19"], lk: ["112", "111"], zx: null, xc: "", vb: [] };
console.log(getCartesian(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }
我正在尝试递归拆分某种对象,如果它具有一些值作为数组。
- 如果没有值是数组,它应该 return 对象原样。
- 如果有一个值是空数组,它应该 return 对象原样,但用空字符串替换该数组值
- 如果有多个数组值,应该return 扁平化分割对象。例如,如果有一个带有数组的对象,例如 :
{
"wq": "e2201b13-aa03-4044-b4e3-1ecb25ef5083",
"we": "2019-08-19T00:00:00",
"er": "2019-09-18T00:00:00",
"rt": "PAID",
"ty": "300.00",
"yu": "27.27",
"ui": "272.73",
"io": "0",
"op": "300.00",
"pa": "8df30d22-5af3-4d61-a420-566ccdad8cdf",
"as": "AUD",
"sd": false,
"df": false,
"fg": "2019-12-04T19:57:48",
"gh": "2019-09-16T00:00:00",
"hj": "0",
"jk": [
"6c9809af-269b-4b86-8b07-78c83a12bd18",
"6c9809af-269b-4b86-8b07-78c83a12bd19"
],
"lk": [
'112',
'111',
],
"zx": null,
"xc": "",
"vb": []
}
它应该 return 一个包含 4 个对象的数组,用于这些对象的所有排列。其中 lk、jk 和 vb 的值是字符串。 vb 永远是空白的,因为它是一个空白对象。如果在源对象中 vb 是这样的 '' 即空白字符串,那将是一样的。 4 个对象,因为有 2 个数组,每个数组有 2 个对象。 2^2 = 4。例如,如果 vb 也有 2 个对象,则将有 2^3=8 个对象,所有其他键都相同,但提到的 3 个键为字符串。
- 数组中的值未知。所以,它可以是任意数量的od值,范围从0-n
- 源对象中可以是数组的键未知。所以需要递归遍历。
- 源对象中的值也可以是null或{}对象,可以忽略。
到目前为止,我已经编写了这样的入门程序:
const result = [];
const reserve = {};
Object.keys(source).forEach((key) => {
if (source[key] instanceof Object) {
// const isArr = Array.isArray(source[key]);
source[key].forEach((element) => {
result.push({
...source,
[key]: element
});
});
} else {
reserve[key] = source[key]
}
})
console.log(result)
// console.log(reserve)
// console.log(result.map(i => Object.assign({}, i, reserve)))
它在某种程度上给了我想要的输出,但仍然需要工作。欢迎任何推荐和建议。
假设您想要获得笛卡尔积并将空数组保留为单个值,您可以关注此数据。
如果包含对象的数组再次调用 getCartesian
并构建新对象,您可以采用递归函数分离所有 key/value 对并通过迭代值构建新的笛卡尔积。
function getCartesian(object) {
return Object.entries(object).reduce((r, [k, v]) => {
var temp = [];
r.forEach(s =>
(Array.isArray(v) && v.length ? v : [v]).forEach(w =>
(w && typeof w === 'object' && (!Array.isArray(w) || w.length) ? getCartesian(w) : [w]).forEach(x =>
temp.push(Object.assign({}, s, { [k]: x }))
)
)
);
return temp;
}, [{}]);
}
var data = { wq: "e2201b13-aa03-4044-b4e3-1ecb25ef5083", we: "2019-08-19T00:00:00", er: "2019-09-18T00:00:00", rt: "PAID", ty: "300.00", yu: "27.27", ui: "272.73", io: "0", op: "300.00", pa: "8df30d22-5af3-4d61-a420-566ccdad8cdf", as: "AUD", sd: false, df: false, fg: "2019-12-04T19:57:48", gh: "2019-09-16T00:00:00", hj: "0", jk: ["6c9809af-269b-4b86-8b07-78c83a12bd18", "6c9809af-269b-4b86-8b07-78c83a12bd19"], lk: ["112", "111"], zx: null, xc: "", vb: [] };
console.log(getCartesian(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }