0

I'm attempting to join an array of objects with the "same" keys as one array. Basically the what I mean by "same keys" is that these keys will vary in only on number, in which doesn't matter. For example:

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

I wan't to join all the keys that have the following syntax into one. Like:

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

I have a array of arrays containing this data.

[{
  "id": "123"
}, {
  "group_name": "Test Group"
}, {
  "admin": "Somthing"
}, {
  "email_address": "[email protected]"
}, {
  "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"
}...
]
...

What I would like to accomplish:

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

For any other keys that have this syntax of:

name.number.id

I would always like to join in a single array with the first part of the name

1
  • Is this with types or in actual code. Commented May 3, 2022 at 14:20

1 Answer 1

1

I would suggest to split the problem in to three parts:

  1. Transform your arrays of { key: value } objects in to single, nested objects
  2. Flatten such nested objects to replace the { id: ... } objects with just their values
  3. Translate back to one-object per key-value-pair

1. Merging to a single object

To build up a nested object, we split each key by ".". We then loop over the keys in pairs to create our nested layers. When a key is numeric, we add an array. See mergeKvp in the snippet below.

2. Flattening to get rid of { id }

To flatten, we traverse the tree. Whenever we see an object that has only an id property, we replace it by that object's id value. See flattenObj in the snippet below.

//// 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": "[email protected]"
}, {
  "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"
}]; };

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.