繁体   English   中英

在对象数组中展平嵌套的 object

[英]Flatten nested object in array of objects

我使用 Typescript 并且我有这个 object 结构:

    {
  a: "somedata",
  b: "somedata2",
  c: [
    {
      name: "item1",
      property1: "foo",
      property2: "bar",
      property3:{property4:"baz",property5:"foo2"},
      property6:"bar2"
    },
    { name: "item2", properties:{...} },
  ]
};

我需要将每个项目的属性设置在同一级别,以便让我的最终 object 像这样:

 {
  a: "somedata",
  b: "somedata2",
  c: [
    {
      name: "item1",
      property1: "foo",
      property2: "bar",
      property4:"baz",
      property5:"foo2",
      property6:"bar2"
    },
    { name: "item2",
      property1:"...",
      property2:"..." },
  ]
};

编辑:这是我现在唯一的东西:

  getFinalObject(objectId){
    
        return this.http.get(
            this.API_URL + "/object/"+objectId,
            this.getHeaders()
          ).pipe(
            map((res:any) =>{//my final object should be mapped here
});
    }

这是一个通用的 function 应该在所有深度都有效(除非你用过深的对象破坏调用堆栈)。

const flatten = <T extends Record<string, any>>(value: T): Record<string, any> =>
    Object.fromEntries(
        Object.entries(value)
            .flatMap(([k, v]) =>
                typeof v === "object" && v !== null
                    ? (Array.isArray(v)
                        ? [[k, v.map(x => typeof x === "object" ? flatten(x) : x)]]
                        : Object.entries(flatten(v)))
                    : [[k, v]]))

游乐场链接

假设没有比您的示例中给出的嵌套级别更高的嵌套,并且嵌套仅发生在键“c”中,那么下面的代码可能就是您的意思。 此外,由于 typescript 在删除和插入时提出的限制,必须使用“any”类型来声明 object。

let s:any =   {
  a: "somedata",
  b: "somedata2",
  c: [
    {
      name: "item1",
      property1: "foo",
      property2: "bar",
      property3:{property4:"baz",property5:"foo2"},
      property6:"bar2"
    },
    { name: "item2", 
      property1: "foo",
      property2: "bar",
      property3:{property4:"baz",property5:"foo2"},
      property6:"bar2"  
    },
  ]
};



for(let i:number=0; i<s.c.length; i++) {
    let KEYS:string[] = Object.keys(s.c[i]);
    let VALS:string[] = Object.values(s.c[i]);
    let tempKEYS:string[] = [];
    let tempVALS:string[] = [];
    for(let j:number=0; j<VALS.length; j++) {
        if(typeof VALS[j] === "object") {
            tempKEYS.push(...Object.keys(VALS[j]));
            tempVALS.push(...Object.values(VALS[j]));
            delete s.c[i][KEYS[j]];
        }
    }
    for(let j:number=0; j< tempKEYS.length;j++) {
        s.c[i][tempKEYS[j]] = tempVALS[j];
    }
}

console.log(s);

另一种方法是使用接口并创建另一个新的 object,从您当前的接口中获取值。 这样,可以避免“任何”类型。

interface Inner {
    [property : string] : string
}

interface Outer {
    a : string,
    b : string,
    c : Inner[]
}

let s:any =   {
  a: "somedata",
  b: "somedata2",
  c: [
    {
      name: "item1",
      property1: "foo",
      property2: "bar",
      property3:{property4:"baz",property5:"foo2"},
      property6:"bar2"
    },
    { name: "item2", 
      property1: "foo",
      property2: "bar",
      property3:{property4:"baz",property5:"foo2"},
      property6:"bar2"  
    },
  ]
};


let newS : Outer = {
    a : s.a,
    b : s.b,
    c : [] 
};



for(let i:number=0; i<s.c.length; i++) {
    newS.c.push({});
    let KEYS:string[] = Object.keys(s.c[i]);
    let VALS:string[] = Object.values(s.c[i]);
    console.log(VALS.length);
    for(let j:number=0; j<VALS.length; j++) {
        if(typeof VALS[j] === 'string') {
            newS.c[i][KEYS[j]] = VALS[j];
        }
        else if(typeof VALS[j] === 'object') {
            let innerKEYS : string[] = Object.keys(VALS[j]);
            let innerVALS : string[] = Object.values(VALS[j]);
            for(let k:number=0; k<innerKEYS.length; k++) {
                newS.c[i][innerKEYS[k]] = innerVALS[k];
            }
        }
    }
}

console.log(newS);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM