将名称为 "same" 的对象键数组连接到一个数组中

Joining array of objects keys with "same" name into one array

我正在尝试使用与一个数组“相同”的键来连接一组对象。基本上,我所说的“相同键”的意思是这些键仅在数量上有所不同,这无关紧要。例如:

{ names.0.id: "Here" }
{ names.1.id: "Almost" }
{ names.2.id: "There" }
...

我不想将具有以下语法的所有键合并为一个。喜欢:

{ names: ["Here", "Almost", "There"] }

我有一个包含这些数据的数组。

[{
  "id": "123"
}, {
  "group_name": "Test Group"
}, {
  "admin": "Somthing"
}, {
  "email_address": "Somthing@here.com"
}, {
  "org.id": "4"
}, {
  "created_by": "6"
}, {
  "updated_by": "6"
}, {
  "students.0.id": "Yes"
}, {
  "students.1.id": "No"
}, {
  "names.0.id": "Here"
}, {
  "names.1.id": "Almost"
}, {
  "names.2.id": "There"
}],
[{
  "id": "125"
}...
]
...

我想完成的事情:

[{
  "id": "123"
}, {
  "group_name": "Test Group"
}, {
  "admin": "Somthing"
}, {
  "email_address": "Somthing@here.com"
}, {
  "org.id": "4"
}, {
  "created_by": "6"
}, {
  "updated_by": "6"
}, {
  "students": ["Yes", "No"]
}, {
  "names": ["Here", "Almost", "There"]
}]

对于具有以下语法的任何其他键:

name.number.id

我总是想用名称的第一部分加入一个数组

我建议将问题分为三个部分:

  1. { key: value } 个对象的数组转换为单个嵌套对象
  2. 展平此类嵌套对象以仅用它们的值替换 { id: ... } 个对象
  3. 根据 key-value-pair
  4. 翻译回 one-object

1。合并为单个对象

为了构建嵌套对象,我们将每个键分开 "."。然后我们成对遍历键以创建我们的嵌套层。当键是数字时,我们添加一个数组。请参阅下面的代码段中的 mergeKvp

2。扁平化去掉 { id }

为了展平,我们遍历树。每当我们看到一个对象只有 id 属性 时,我们将其替换为该对象的 id 值。请参阅下面代码段中的 flattenObj

//// UTILS
// Merge a key value pair in to an object splitting by "."
const mergeKvp = (obj, [key, value]) => {
  const path = key.split(".");
  
  let target = obj;
  for (let i = 0; i < path.length - 1; i += 1) {
    const k1 = path[i];
    const k2 = path[i + 1];
    
    if (!target[k1]) target[k1] = isNaN(+k2) ? {} : [];
    
    target = target[k1];
  }
  
  target[path.at(-1)] = value;
  
  return obj;
}

// Flatten a nested object structure
const flattenObj = obj => {
  // Handle arrays
  if (Array.isArray(obj)) return obj.map(flattenObj);
  
  // Handle objects
  if (Object(obj) === obj) {
    // Replace { id: _ } objects with _
    if ("id" in obj && Object.keys(obj).length === 1) return obj.id;
    
    // Recurse for other objects
    return Object.fromEntries(
      Object.entries(obj).map(([k, v]) => [k, flattenObj(v)])
    );
  }
  
  // Return value for everything else
  return obj;
}

//// APP
// Merge KVP objects in to one big object
const base = Object.assign({}, ...getData());

// Create nested structures out of the dot-keys
const tree = Object.entries(base).reduce(mergeKvp, {})

// Flatten the tree
const output = flattenObj(tree);

// Translate back to array of { key: value } objects
console.log(
  Object.entries(output).map(([k, v]) => ({ [k]: v }))
);


function getData() { return [{
  "id": "123"
}, {
  "group_name": "Test Group"
}, {
  "admin": "Somthing"
}, {
  "email_address": "Somthing@here.com"
}, {
  "org.id": "4"
}, {
  "created_by": "6"
}, {
  "updated_by": "6"
}, {
  "students.0.id": "Yes"
}, {
  "students.1.id": "No"
}, {
  "names.0.id": "Here"
}, {
  "names.1.id": "Almost"
}, {
  "names.2.id": "There"
}]; };