Moe Elsharif
Moe Elsharif

Reputation: 358

How to destructure an array of objects into several arrays, one per property?

I am trying to destructure an array of objects with three properties into three separate arrays for example

maybe something like

const {wlAddresses,wlTokens,wlTickets} = Object.map()

or

const [wlAddresses,wlTokens,wlTickets] = Object.map()

Where Object.map() returns something like this

[{ wlAddresses: '23',
    wlTokens: 1,
    wlTickets: 3 },
  { wlAddresses: '24',
    wlTokens: 1,
    wlTickets: 2 },
  { wlAddresses: '25',
    wlTokens: 1,
    wlTickets: 3 }]

I tried with that method and it only returns the first object, not the ones after. I know I can solve this problem by mapping the object and returning everything as separate arrays but maybe I can use destructuring to do this.

NOTE: Its just a question of can be done or not, I am not forcing an answer

Upvotes: 0

Views: 5223

Answers (4)

dumbass
dumbass

Reputation: 27202

Here’s a lazy-evaluated solution using a Proxy:

const lazySOA = aos => {
  return new Proxy(Object.create(null), {
    get(_, key) { return aos.map(s => s[key]); }
  });
};

const data = [
  { wlAddresses: '23',
    wlTokens: 1,
    wlTickets: 3 },
  { wlAddresses: '24',
    wlTokens: 1,
    wlTickets: 2 },
  { wlAddresses: '25',
    wlTokens: 1,
    wlTickets: 3 },
];

const { wlAddresses, wlTokens, wlTickets } = lazySOA(data);

console.log(wlAddresses);
console.log(wlTokens);
console.log(wlTickets);

(Not that much of a fan of Proxy myself, but in a use this limited it should not cause problems.)

Upvotes: 0

guest271314
guest271314

Reputation: 1

You can use nested loops and Object.entries()

let o = [{"wlAddresses":"23","wlTokens":1,"wlTickets":3},{"wlAddresses":"24","wlTokens":1,"wlTickets":2},{"wlAddresses":"25","wlTokens":1,"wlTickets":3}];

let entries = Object.entries(o);
    let res = Array.from({length:entries.length}).fill([]);
    for (let [, {wlAddresses,wlTokens,wlTickets}] of entries) {   
      Object.entries({wlAddresses,wlTokens,wlTickets})
      .forEach(([, prop], index) => {
        res[index] = [...res[index], prop]
      })
    }
    
let [wlAddresses,wlTokens,wlTickets] = res;

console.log(wlAddresses,wlTokens,wlTickets);

Using destructuring assignment alone

let o = [{"wlAddresses":"23","wlTokens":1,"wlTickets":3},{"wlAddresses":"24","wlTokens":1,"wlTickets":2},{"wlAddresses":"25","wlTokens":1,"wlTickets":3}];

let len = o.length;

let [wlAddresses,wlTokens,wlTickets] = Array.from({length:len}, () => []);

let i = 0;

if (i < len) {
  ({wlAddresses:wlAddresses[wlAddresses.length]
  , wlTokens:wlTokens[wlTokens.length]
  , wlTickets:wlTickets[wlTickets.length]} = o[i]);
  console.log(wlAddresses,wlTokens,wlTickets);
  ++i;
} else {
  console.log("done");
  console.log(wlAddresses,wlTokens,wlTickets);
}

if (i < len) {
  ({wlAddresses:wlAddresses[wlAddresses.length]
  , wlTokens:wlTokens[wlTokens.length]
  , wlTickets:wlTickets[wlTickets.length]} = o[i]);
  console.log(wlAddresses,wlTokens,wlTickets);
  ++i;
} else {
  console.log("done");
  console.log(wlAddresses,wlTokens,wlTickets);
}

if (i < len) {
  ({wlAddresses:wlAddresses[wlAddresses.length]
  , wlTokens:wlTokens[wlTokens.length]
  , wlTickets:wlTickets[wlTickets.length]} = o[i]);
  console.log(wlAddresses,wlTokens,wlTickets);
  ++i;
} else {
  console.log("done");
  console.log(wlAddresses,wlTokens,wlTickets);
}

if (i < len) {
  ({wlAddresses:wlAddresses[wlAddresses.length]
  , wlTokens:wlTokens[wlTokens.length]
  , wlTickets:wlTickets[wlTickets.length]} = o[i]);
  console.log(wlAddresses,wlTokens,wlTickets);
  ++i;
} else {
  console.log("done");
  console.log(wlAddresses,wlTokens,wlTickets);
}

Using a loop with code at second hardcoded snippet

let o = [{"wlAddresses":"23","wlTokens":1,"wlTickets":3},{"wlAddresses":"24","wlTokens":1,"wlTickets":2},{"wlAddresses":"25","wlTokens":1,"wlTickets":3}];

let len = o.length;

let [wlAddresses,wlTokens,wlTickets] = [[], [], []];

let i = 0;

while (i < len) {
  ({wlAddresses:wlAddresses[wlAddresses.length]
  , wlTokens:wlTokens[wlTokens.length]
  , wlTickets:wlTickets[wlTickets.length]} = o[i]);
  ++i;
}
  
console.log("done");
console.log(wlAddresses,wlTokens,wlTickets);

Upvotes: 0

Mark
Mark

Reputation: 92440

Destructuring is great when you have an object or array and need to pull out specific items, but that's not the case here. Your data is not a simple object or array — it's an array of objects. You're not going to be able to do this with a simple assignment. You will need to transform your data into the format you want. For example something like this:

let arr = [{
    wlAddresses: '23',
    wlTokens: 1,
    wlTickets: 3
  },
  {
    wlAddresses: '24',
    wlTokens: 1,
    wlTickets: 2
  },
  {
    wlAddresses: '25',
    wlTokens: 1,
    wlTickets: 3
  }
]

let r = arr.reduce((acc, curr) => {
    for ([key, value] of Object.entries(curr)) {
        if (! acc[key]) acc[key] = []
        acc[key].push( curr[key])
    }
    return acc
}, {})


const {wlAddresses,wlTokens,wlTickets} = r

console.log(wlAddresses,wlTokens,wlTickets)

Upvotes: 3

kind user
kind user

Reputation: 41893

Assuming that every object inside your array will have exactly the same keys, you could just map it.

const data = [{wlAddresses:'23',wlTokens:1,wlTickets:3},{wlAddresses:'24',wlTokens:1,wlTickets:2},{wlAddresses:'25',wlTokens:1,wlTickets:3}];
    
const r = Object.keys(data[0]).map((v) => ({ [v]: data.map((c) => c[v]) }));

console.log(JSON.stringify(r));

Upvotes: 2

Related Questions