Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

122
Views
generic function to create an array of nested objects from a single object of arrays

This is a very specific problem but I have an object with arrays:

let rawData = {
    one: ["a", "a", "a", "b", "b", "b", "c", "c", "c"],
    two: [1,2,3,1,2,3,1,2,3],
    three: [1,4,9,3,9,7,6,5,5]
  }

and I want to write a generic function that will create a set of nested objects based on the first array (here a, but I'd like to make this function not dependent on a specific key.

In my first try I wrote a function that parses this into an array of objects:

dataframe_for_plot = (data) => {
  var length
  var names = []
  for (var name in data) {
        if (data.hasOwnProperty(name))
            names.push(name);
        length = rawData[name].length;
  }

    var results = [];
    var item;
    for (var row = 0; row < length; row++) {
        item = {};
        for (var col = 0; col < names.length; col++) {
            item[names[col]] = data[names[col]][row];
        }
        results.push(item);
    }
    return results;
}

Which yeilds

dataframe_for_plot(rawData)
[
  {one: "a", two: 1, three: 1},
  {one: "a", two: 2, three: 4},
  {one: "a", two: 3, three: 9},
  {one: "b", two: 1, three: 3},
  {one: "b", two: 2, three: 9},
  {one: "b", two: 3, three: 7},
  {one: "c", two: 1, three: 6},
  {one: "c", two: 2, three: 5},
  {one: "c", two: 3, three: 5},
]

But I want to build on this function to get my desired output where the first key is used to create objects based on the unique number of that key (3 in this case), and a new value key is created to contain a nested array of the other keys (two and three in this case, grouped together by one)

let desired_output = [
  {
    one:"a",
    values: [
      {two:1, three:1},
      {two:2, three:4},
      {two:3, three:9}
    ],
  },
    {
    one:"b",
    values: [
      {two:1, three:3},
      {two:2, three:9},
      {two:3, three:7}
    ],
  },
    {
    one:"c",
    values: [
      {two:1, three:6},
      {two:2, three:5},
      {two:3, three:5}
    ],
  }
]

I think my function is a good start, but I need a little help working on the nested part 2! Thanks!

about 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Convert the object to an array of entries, and get the 1st item's key and vals. Reduce the vals to a Map. The Map would have a single object for each unique value from the 1st array if values (one in your case). Then iterate the array of the other values, take the respective value from each [key, arr] pair, and convert them to an object using Object.fromEntries().

Convert the Map values iterator back to an array using Array.from().

const fn = obj => {
  const [[key, vals], ...values] = Object.entries(obj)
  
  return Array.from(vals.reduce((acc, v, i) => {
    if(!acc.has(v)) acc.set(v, { [key]: v, values: [] })
    
    acc.get(v).values.push(Object.fromEntries(
      values.map(([k, arr]) => [k, arr[i]])
    ))
    
    return acc
  }, new Map()).values())
}

const rawData = {
  one: ["a", "a", "a", "b", "b", "b", "c", "c", "c"],
  two: [1,2,3,1,2,3,1,2,3],
  three: [1,4,9,3,9,7,6,5,5]
}

const result = fn(rawData)

console.log(result)

If you want to control the order of properties, you can pass an order array, and then create the entries manually in the order you've stated:

const fn = (order, obj) => {
  const [[key, vals], ...values] = order.map(key => [key, obj[key]])
  
  return Array.from(vals.reduce((acc, v, i) => {
    if(!acc.has(v)) acc.set(v, { [key]: v, values: [] })
    
    acc.get(v).values.push(Object.fromEntries(
      values.map(([k, arr]) => [k, arr[i]])
    ))
    
    return acc
  }, new Map()).values())
}

const rawData = {
  one: ["a", "a", "a", "b", "b", "b", "c", "c", "c"],
  two: [1,2,3,1,2,3,1,2,3],
  three: [1,4,9,3,9,7,6,5,5]
}

const result = fn(['one', 'three', 'two'], rawData)

console.log(result)

about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!