将具有子数组的对象数组映射和减少到具有父 ID 的子数组

Posted

技术标签:

【中文标题】将具有子数组的对象数组映射和减少到具有父 ID 的子数组【英文标题】:Map and reduce array of objects with a children array down to array of children with parent's id 【发布时间】:2018-01-26 04:27:56 【问题描述】:

我正在尝试获取这样的对象数组

[
  
    "id": "uniqueParentId1",
    "children": [
      
        "childProp1": "test1",
        "childProp2": "test3"
      
    ]
  ,
  
    "id": "uniqueParentId2",
    "children": [
      
        "childProp1": "somevals",
        "childProp2": "other vals"
      ,
      
        "childProp1": "somevals 1",
        "childProp2": "other vals 1"
      
    ]
  
]

并返回一个由所有子对象组合而成的数组,每个子对象都有一个附加值,即父对象的“id”。

上面的例子,结果。

[
  
    "parentId": "uniqueParentId1",
    "childProp1": "test1",
    "childProp2": "test3"
  ,
  
    "parentId": "uniqueParentId2",
    "childProp1": "somevals",
    "childProp2": "other vals"
  
  
    "parentId": "uniqueParentId2",
    "childProp1": "somevals 1",
    "childProp2": "other vals 1"
  
]

我只是不确定如何处理这个问题。我熟悉扁平化和数组数组。但是我只能在不添加 parentId 的情况下将输出作为原始子项的数组获取

【问题讨论】:

解释更多 FTW 的较短标题 不知道怎么解释更短 例如Howto use Map reduce to reorganise an array of objects。你一提到:父母、孩子、身份证,它就以为我在读你的描述,而不是你的标题。 【参考方案1】:

应该这样做:

var values = [
    "id": "uniqueParentId1",
    "children": [
      "childProp1": "test1",
      "childProp2": "test3"
    ]
  ,
  
    "id": "uniqueParentId2",
    "children": [
        "childProp1": "somevals",
        "childProp2": "other vals"
      ,
      
        "childProp1": "somevals 1",
        "childProp2": "other vals 1"
      
    ]
  
];

var result = values.map(value =>
  value.children.map(child => ( parentId: value.id, ...child ))
).flat();

console.log(result);

代码分解:

child => ( parentId: value.id , ...child )

获取一个对象并返回一个具有parentId 属性和child 中所有属性的新对象。

输入:


    "childProp1": "somevals",
    "childProp2": "other vals"

输出:


    "parentId": "uniqueParentId2"
    "childProp1": "somevals",
    "childProp2": "other vals"

下一个函数:

value =>
    value.children.map(child => ( parentId: value.id, ...child ))

获取一个名为value 的对象,将上述函数应用于value.children 中的每个数组元素,并返回一个结果数组。

下一个:

values.map(.....)

将上述函数应用于values 中的每个元素并返回结果数组。

此时,.map() 调用的结果是一个如下所示的数组,原始数组的每个元素对应一个元素:

[
  [
    
      "parentId": "uniqueParentId1",
      "childProp1": "test1",
      "childProp2": "test3"
    
  ],
  [
    
      "parentId": "uniqueParentId2",
      "childProp1": "somevals",
      "childProp2": "other vals"
    ,
    
      "parentId": "uniqueParentId2",
      "childProp1": "somevals 1",
      "childProp2": "other vals 1"
    
  ]
]

所以我们要做的最后一件事是用.flat() 展平这个数组。

【讨论】:

喜欢您的解决方案!也许添加几行解释您的代码,以便其他不熟悉函数式 js 的人可以理解您的解决方案? @AP。谢谢你的建议。加了个解释,结果发现不止几行。 :) 很好的解决方案,谢谢!如果有多个嵌套数组/对象,你会怎么做?【参考方案2】:
const arr = [
  
    "id": "uniqueParentId1",
    "children": [
      
        "childProp1": "test1",
        "childProp2": "test3"
      
    ]
  ,
  
    "id": "uniqueParentId2",
    "children": [
      
        "childProp1": "somevals",
        "childProp2": "other vals"
      ,
      
        "childProp1": "somevals 1",
        "childProp2": "other vals 1"
      
    ]
  
];
let combined = [];
arr.forEach((parent) => 
  const id, children = parent;
  children.forEach((child) => 
    Object.assign(child, 
      parentId: id
    );
    combined.push(child);
  );
);

console.log(combined);
/*
[
  
    "parentId": "uniqueParentId1",
    "childProp1": "test1",
    "childProp2": "test3"
  ,
  
    "parentId": "uniqueParentId2",
    "childProp1": "somevals",
    "childProp2": "other vals"
  
  
    "parentId": "uniqueParentId2",
    "childProp1": "somevals 1",
    "childProp2": "other vals 1"
  
]
*/

【讨论】:

【参考方案3】:

如果您应用更实用的方法,您可以执行以下操作:

const results = [] //Array we want to store all data in
arr.forEach(e => 
  const id: parentId = e  //Extract id as variable parentId

  // Store all the children objects with the added key
  e.children.forEach(c => results.push(Object.assign(parentId, c)))
)

【讨论】:

以上是关于将具有子数组的对象数组映射和减少到具有父 ID 的子数组的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB:使用子代数组填充父代vs通过父代ID搜索子代

如何将树状的数组和对象的嵌套数据结构转换为具有计算/计数 id 和跟踪父 id 的项目列表?

如何将 JOIN 映射到具有子结构数组的结构数组

映射具有用户 ID 的对象数组并从此用户 ID 获取用户详细信息

尝试反序列化 JSON 对象数组,其中对象具有数组作为属性。我可以将数组元素映射到类的特定属性吗?

使用 LINQ 从具有嵌套数组的类中获取子属性值和父属性值