【问题标题】:Flatten nested object in array of objects展平对象数组中的嵌套对象
【发布时间】:2021-03-22 20:02:51
【问题描述】:

我正在使用 Typescript,我有这个对象结构:

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

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

 {
  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
});
    }

【问题讨论】:

  • properties 对象可以有自己的properties 对象吗?嵌套对象可以有多深(无限深?)
  • 请向我们展示您尝试过的代码
  • 我的属性对象内部最多可以有 2 个深度级别(嵌套对象),我只需要将它们全部放在一个级别中。
  • 你能举个更多关卡的例子吗?

标签: javascript typescript object ecmascript-6


【解决方案1】:

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

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);

另一种方法是使用接口并创建另一个新对象,从当前对象中获取值。这样就可以避免“any”类型。

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);

【讨论】:

    【解决方案2】:

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

    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]]))
    

    Playground link

    【讨论】:

    • 我可能会为了好玩而适当地保留字体,但这是一项更复杂的工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 2018-10-24
    • 2013-11-06
    • 1970-01-01
    • 2021-07-04
    • 2016-05-18
    相关资源
    最近更新 更多