动态展平嵌套对象数组 javascript
dynamically flatten nested array of objects javascript
我正在尝试编写一个函数来接受嵌套对象数组,并动态地 return 扁平化结果。 arrayProperties.filter()
并不是像我期望的那样 return 对象数组。
const data = [
{
parKeyA: "parValA",
parKeyA1:
{chiKeyA1: "chiValA1", chiKeyA2: "chiValA2"},
parKeyA2: {chiKeyA3: "chiValA3"}
},
{
parKeyB: "parValB",
parKeyB1:
{chiKeyB1:"chiValB1"}
}
]
flatData = flatNestedObjArray(data);
console.log(flatData);
function flatNestedObjArray(array) {
let flatArray = array.map(element => {
let arrayProperties = Object.entries(element);
//filter not returning array of objects
let nestedObjects = arrayProperties.filter(property => {
const parentValue = property[1];
if (typeof parentValue === "object" && parentValue !== null) {
return parentValue;
}
});
//nestedObjects should be array of objects
let merged = nestedObjects.map(obj => element.concat(obj));
return merged;
});
return flatArray;
}
预期结果:
const data = [
{
parKeyA: "parValA",
chiKeyA1: "chiValA1",
chiKeyA2: "chiValA2",
chiKeyA2: "chiValA2"
},
{
parKeyB: "parValB",
chiKeyB1:"chiValB1"
}
]
您可以使用对象 属性 循环,使用 in
关键字为每个级别使用递归
for(var prop in data) {
....
}
我使用了一种旧的递归技术从一个工作代码开始
function flatten(data) {
var newData = {};
for(var prop in data) {
if(typeof data[prop] == "object") {
var childs = flatten(data[prop])
for(var cprop in childs){
newData[cprop] = childs[cprop];
}
}else {
newData[prop] = data[prop]
}
}
return newData;
}
for(var i=0;i<data.length;i++)
data[i] = flatten(data[i]);
console.log(data);
您需要处理重复项
您可以使用递归将对象展平为单级对象,并将该函数传递给 map 以获得展平对象数组
const data = [{
parKeyA: "parValA",
parKeyA1: {
chiKeyA1: "chiValA1",
chiKeyA2: "chiValA2"
},
parKeyA2: {
chiKeyA3: "chiValA3"
}
},
{
parKeyB: "parValB",
parKeyB1: {
chiKeyB1: "chiValB1",
chiKeyB2: {}
}
}
]
let flatten = (obj, final = {}) => {
for (let key in obj) {
if (typeof obj[key] === 'object' && obj[key] != null) {
flatten(obj[key], final)
} else {
final[key] = obj[key]
}
}
return final
}
console.log(data.map((v) => flatten(v)))
您可以使用 map
这将 return 一个数组和一个递归函数。已在代码中添加注释,希望有用
const data = [{
parKeyA: "parValA",
parKeyA1: {
chiKeyA1: "chiValA1",
chiKeyA2: "chiValA2"
},
parKeyA2: {
chiKeyA3: "chiValA2"
}
},
{
parKeyB: "parValB",
parKeyB1: {
chiKeyB1: "chiValB1"
}
}
]
/* Recursive function.It will take a object,iterate the object and check if the value of the key is another object. If it is another object then call same recursive function */
function getFlatObj(obj) {
let newObject = {}
function doRecurssion(currObj) {
// iterate through the object
for (let keys in currObj) {
// check if the value is another object
if (typeof currObj[keys] === 'object' && typeof currObj[keys] !== null) {
doRecurssion(currObj)
} else {
// if not another object then add key and value
newObject[keys] = currObj[keys]
}
}
return newObject;
}
return doRecurssion(obj);
}
let flatObj = data.map((item) => {
const acc = {};
for (let keys in item) {
if (typeof item[keys] === 'object' && typeof item[keys] !== null) {
Object.assign(acc, getFlatObj(item[keys]))
} else {
acc[keys] = item[keys]
}
}
return acc;
}, {});
console.log(flatObj)
Object.entries()
获取一个对象并将其转换为二维数组:
let object = {keyA: "valueA", keyB: "valueB", keyC: {kA: "vA", kB: "vB"}};
let array = Object.entries(object);
// array = [["keyA", "valueA"], ["keyB", "valueB"], ["keyC", {kA: "vA", kB: "vB"}]];
在 for...of
循环中使用上面的代码,每个条目都可以被解构:
for (let [key, value] of Object.entries(object)) {...
声明一个空数组并遍历对象数组中的每个对象文字:
let array = [];
for (let obj of objArray) {...
在每个对象上,声明一个空对象,然后将每个对象的每个key/value转换成一个子数组:
let object = {};
for (let [key, value] of Object.entries(obj)) {...
检查每个对象字面量的每个值——如果该值是对象字面量...
if (Object.prototype.toString.call(value) == "[object Object]") {...
...遍历值并将每个 key/value 分配给空对象...
for (let [k, v] of Object.entries(value)) {
object[k] = v;
}
...否则将key/value分配给空对象...
} else {
object[key] = value;
}
将新对象推入新数组:
array.push(object);
演示
const data = [{
parKeyA: "parValA",
parKeyA1: {
chiKeyA1: "chiValA1",
chiKeyA2: "chiValA2"
},
parKeyA2: {
chiKeyA3: "chiValA3"
}
},
{
parKeyB: "parValB",
parKeyB1: {
chiKeyB1: "chiValB1"
}
}
];
function subObjToKeyVal(objArr) {
let array = [];
for (let obj of objArr) {
let object = {};
for (let [key, value] of Object.entries(obj)) {
if (Object.prototype.toString.call(value) == "[object Object]") {
for (let [k, v] of Object.entries(value)) {
object[k] = v;
}
} else {
object[key] = value;
}
}
array.push(object);
}
return array;
}
console.log(subObjToKeyVal(data));
我正在尝试编写一个函数来接受嵌套对象数组,并动态地 return 扁平化结果。 arrayProperties.filter()
并不是像我期望的那样 return 对象数组。
const data = [
{
parKeyA: "parValA",
parKeyA1:
{chiKeyA1: "chiValA1", chiKeyA2: "chiValA2"},
parKeyA2: {chiKeyA3: "chiValA3"}
},
{
parKeyB: "parValB",
parKeyB1:
{chiKeyB1:"chiValB1"}
}
]
flatData = flatNestedObjArray(data);
console.log(flatData);
function flatNestedObjArray(array) {
let flatArray = array.map(element => {
let arrayProperties = Object.entries(element);
//filter not returning array of objects
let nestedObjects = arrayProperties.filter(property => {
const parentValue = property[1];
if (typeof parentValue === "object" && parentValue !== null) {
return parentValue;
}
});
//nestedObjects should be array of objects
let merged = nestedObjects.map(obj => element.concat(obj));
return merged;
});
return flatArray;
}
预期结果:
const data = [
{
parKeyA: "parValA",
chiKeyA1: "chiValA1",
chiKeyA2: "chiValA2",
chiKeyA2: "chiValA2"
},
{
parKeyB: "parValB",
chiKeyB1:"chiValB1"
}
]
您可以使用对象 属性 循环,使用 in
关键字为每个级别使用递归
for(var prop in data) {
....
}
我使用了一种旧的递归技术从一个工作代码开始
function flatten(data) {
var newData = {};
for(var prop in data) {
if(typeof data[prop] == "object") {
var childs = flatten(data[prop])
for(var cprop in childs){
newData[cprop] = childs[cprop];
}
}else {
newData[prop] = data[prop]
}
}
return newData;
}
for(var i=0;i<data.length;i++)
data[i] = flatten(data[i]);
console.log(data);
您需要处理重复项
您可以使用递归将对象展平为单级对象,并将该函数传递给 map 以获得展平对象数组
const data = [{
parKeyA: "parValA",
parKeyA1: {
chiKeyA1: "chiValA1",
chiKeyA2: "chiValA2"
},
parKeyA2: {
chiKeyA3: "chiValA3"
}
},
{
parKeyB: "parValB",
parKeyB1: {
chiKeyB1: "chiValB1",
chiKeyB2: {}
}
}
]
let flatten = (obj, final = {}) => {
for (let key in obj) {
if (typeof obj[key] === 'object' && obj[key] != null) {
flatten(obj[key], final)
} else {
final[key] = obj[key]
}
}
return final
}
console.log(data.map((v) => flatten(v)))
您可以使用 map
这将 return 一个数组和一个递归函数。已在代码中添加注释,希望有用
const data = [{
parKeyA: "parValA",
parKeyA1: {
chiKeyA1: "chiValA1",
chiKeyA2: "chiValA2"
},
parKeyA2: {
chiKeyA3: "chiValA2"
}
},
{
parKeyB: "parValB",
parKeyB1: {
chiKeyB1: "chiValB1"
}
}
]
/* Recursive function.It will take a object,iterate the object and check if the value of the key is another object. If it is another object then call same recursive function */
function getFlatObj(obj) {
let newObject = {}
function doRecurssion(currObj) {
// iterate through the object
for (let keys in currObj) {
// check if the value is another object
if (typeof currObj[keys] === 'object' && typeof currObj[keys] !== null) {
doRecurssion(currObj)
} else {
// if not another object then add key and value
newObject[keys] = currObj[keys]
}
}
return newObject;
}
return doRecurssion(obj);
}
let flatObj = data.map((item) => {
const acc = {};
for (let keys in item) {
if (typeof item[keys] === 'object' && typeof item[keys] !== null) {
Object.assign(acc, getFlatObj(item[keys]))
} else {
acc[keys] = item[keys]
}
}
return acc;
}, {});
console.log(flatObj)
Object.entries()
获取一个对象并将其转换为二维数组:
let object = {keyA: "valueA", keyB: "valueB", keyC: {kA: "vA", kB: "vB"}};
let array = Object.entries(object);
// array = [["keyA", "valueA"], ["keyB", "valueB"], ["keyC", {kA: "vA", kB: "vB"}]];
在 for...of
循环中使用上面的代码,每个条目都可以被解构:
for (let [key, value] of Object.entries(object)) {...
声明一个空数组并遍历对象数组中的每个对象文字:
let array = []; for (let obj of objArray) {...
在每个对象上,声明一个空对象,然后将每个对象的每个key/value转换成一个子数组:
let object = {}; for (let [key, value] of Object.entries(obj)) {...
检查每个对象字面量的每个值——如果该值是对象字面量...
if (Object.prototype.toString.call(value) == "[object Object]") {...
...遍历值并将每个 key/value 分配给空对象...
for (let [k, v] of Object.entries(value)) { object[k] = v; }
...否则将key/value分配给空对象...
} else { object[key] = value; }
将新对象推入新数组:
array.push(object);
演示
const data = [{
parKeyA: "parValA",
parKeyA1: {
chiKeyA1: "chiValA1",
chiKeyA2: "chiValA2"
},
parKeyA2: {
chiKeyA3: "chiValA3"
}
},
{
parKeyB: "parValB",
parKeyB1: {
chiKeyB1: "chiValB1"
}
}
];
function subObjToKeyVal(objArr) {
let array = [];
for (let obj of objArr) {
let object = {};
for (let [key, value] of Object.entries(obj)) {
if (Object.prototype.toString.call(value) == "[object Object]") {
for (let [k, v] of Object.entries(value)) {
object[k] = v;
}
} else {
object[key] = value;
}
}
array.push(object);
}
return array;
}
console.log(subObjToKeyVal(data));