动态展平javascript对象的嵌套数组

动态展平javascript对象的嵌套数组,javascript,arrays,nested-object,Javascript,Arrays,Nested Object,我正在尝试编写一个函数,该函数将接受嵌套对象数组,并动态返回展平结果arrayProperties.filter()没有像我预期的那样返回对象数组 const data = [ { parKeyA: "parValA", parKeyA1: {chiKeyA1: "chiValA1", chiKeyA2: "chiValA2"}, parKeyA2: {chiKeyA3: "chiValA3"} },

我正在尝试编写一个函数,该函数将接受嵌套对象数组,并动态返回展平结果
arrayProperties.filter()
没有像我预期的那样返回对象数组

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"
    }
]

对于使用递归的每个级别,可以在关键字中使用
来使用对象属性循环

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);
函数展平(数据){
var newData={};
用于(数据中的var prop){
if(数据类型[prop]=“对象”){
var childs=展平(数据[prop])
for(儿童中的变量cprop){
newData[cprop]=childs[cprop];
}
}否则{
newData[prop]=数据[prop]
}
}
返回新数据;
}

对于(var i=0;i,可以使用递归将对象展平为单个级别的对象,并将该函数传递给map以获得展平对象的数组

const数据=[{
帕克亚:“帕瓦拉”,
公园1:{
骑士1:“骑士精神”,
骑士2:“骑士2”
},
公园2:{
骑士3:“骑士3”
}
},
{
帕克伊布:“帕瓦布”,
公园B1:{
骑士1:“骑士1”,
chiKeyB2:{}
}
}
]
让展平=(obj,final={})=>{
用于(输入obj){
if(对象[键]=='object'&&obj[键]!=null的类型){
展平(obj[键],最终)
}否则{
最终[键]=对象[键]
}
}
返回决赛
}

console.log(data.map((v)=>flant(v))
您可以使用
map
返回数组和递归函数。在代码中添加了注释,希望这会有用

const数据=[{
帕克亚:“帕瓦拉”,
公园1:{
骑士1:“骑士精神”,
骑士2:“骑士2”
},
公园2:{
骑士3:“骑士2”
}
},
{
帕克伊布:“帕瓦布”,
公园B1:{
骑士1:“骑士1”
}
}
]
/*递归函数。它将获取一个对象,迭代该对象并检查键的值是否是另一个对象。如果是另一个对象,则调用相同的递归函数*/
函数getFlatObj(obj){
让newObject={}
功能数据加密(currObj){
//遍历对象
for(将钥匙输入currObj){
//检查该值是否为另一个对象
if(当前对象的类型[键]=='object'&&typeof当前对象的类型[键]!==null){
多勒克松(currObj)
}否则{
//如果不是另一个对象,则添加键和值
newObject[keys]=currObj[keys]
}
}
返回newObject;
}
返回数据保存(obj);
}
设flatObj=data.map((项)=>{
常量acc={};
用于(让项中的键){
if(项的类型[键]=='object'&&typeof项的类型[键]!==null){
分配对象(acc、getFlatObj(项[键])
}否则{
acc[键]=项目[键]
}
}
返回acc;
}, {});
console.log(flatObj)
获取一个对象并将其转换为二维数组:

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 (let [key, value] of Object.entries(object)) {...

  • 声明空数组并遍历对象数组中的每个对象文字:

    let array = [];
    for (let obj of objArray) {...
    
  • 在每个对象上,声明一个空对象,然后将每个对象的每个键/值转换为子数组:

    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;
    }
    
  • …否则,将键/值指定给空对象

    for (let [k, v] of Object.entries(value)) {
      object[k] = v;
    }
    
    } else {
      object[key] = value;
    }
    
  • 将新对象推送到新阵列:

    array.push(object);
    

  • 演示
    const数据=[{
    帕克亚:“帕瓦拉”,
    公园1:{
    骑士1:“骑士精神”,
    骑士2:“骑士2”
    },
    公园2:{
    骑士3:“骑士3”
    }
    },
    {
    帕克伊布:“帕瓦布”,
    公园B1:{
    骑士1:“骑士1”
    }
    }
    ];
    功能子对象(objArr){
    让数组=[];
    对于(让obj代表objArr){
    让对象={};
    for(让Object.entries(obj))的[key,value]{
    if(Object.prototype.toString.call(value)=“[Object Object]”){
    for(让[k,v]为对象项(值)){
    对象[k]=v;
    }
    }否则{
    对象[键]=值;
    }
    }
    array.push(对象);
    }
    返回数组;
    }
    
    console.log(subObjToKeyVal(data));
    与使用Array.map()有很大区别吗除了变量赋值?这段代码在我的机器上运行,我希望它能帮助您从这开始,然后用map或filter@BrettB唯一的区别是赋值将修改原始传递的数组,而当您使用map时,它将创建一个新数组。展平适用于数组而不是对象。例如
    [1,2,3]
    展平为
    1,2,3
    。此外,具有重复键的对象无效。例如,
    chiKeyA2
    在第一个对象中出现两次。@zer00ne修复了重复键…您会将其称为什么?另外,您对如何解决此问题有何帮助?查看您期望的结果…模式如下所示:1.ob中的每个对象ject必须将其键/值移动到父对象。2.然后删除空对象。这没有多大意义…但如果这是您真正想要的,有一种方法可以做到。我将发布一个答案。谢谢您的答案。所有答案都很好,所选答案略短!谢谢。这是一个非常简单明了的答案。我正在查看谢谢你这样的礼物。非常感谢