Q:

Build one object by using array of objects (recursively with subobjects)

Maybe someone can help here.
What I want to do is:

Build one result obj that consists of all the attributes / subobjects of all of these objects in the array
Always have only arrays in the result obj
Recursively build this object (as I don't know how many levels there could be and I don't know the names of the objects)
The order of the attributes is not relevant
Managable Except / black list for some attributes (such as id)

const arr = [{
    id: 0,
    nickname: 'Testnick 0',
    loel: {
      nice: 'like it',
    },
    rating: {
      abc: 5,
      helloworld: 2,
    },
  },
  {
    id: 1,
    nickname: 'Testnick 2',
    rating: {
      abc: 4,
      moep: 1,
    },
  },
  {
    id: 2,
    nickname: 'Testnick 3',
    rating: {
      abc: 40,
      sun: 20,
      anotherObj: {
        tr: 34,
        subsubobj: {
          sd: 24,
        },
      },
    },
  },
];

So the resultobj would look similar to this:

const result = {
  id: [0, 1, 2],
  nickname: ['Testnick 0', 'Testnick 2', 'Testnick 3'],
  loel: {
    nice: ['like it'],
  },
  rating: {
    abc: [5, 4, 40],
    helloworld: [2],
    moep: [1],
    sun: [20],
    anotherObj: {
      tr: [34],
      subsubobj: {
        sd: [24],
      },
    },
  },
};

Can someone help here?

A:

You coud reduce the given array and iterate the object's keys and values recursively for nested objects.

function setValues(target, source) {
    Object.entries(source).forEach(([k, v]) => {
        if (v && typeof v === 'object') {
            setValues(target[k] = target[k] || {}, v);
        } else {
            target[k] = target[k] || [];
            target[k].push(v);
        }
    });
    return target;
}

var data = [{ id: 0, nickname: 'Testnick 0', loel: { nice: 'like it' }, rating: { abc: 5, helloworld: 2 } }, { id: 1, nickname: 'Testnick 2', rating: { abc: 4, moep: 1 } }, { id: 2, nickname: 'Testnick 3', rating: { abc: 40, sun: 20, anotherObj: { tr: 34, subsubobj: { sd: 24 } } } }],
    result = data.reduce(setValues, {});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

