0

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

Moe Elsharif
  • 358
  • 2
  • 10
  • You will create a const variables which cannot be overwritten. – kind user Nov 08 '17 at 19:14
  • Are you saying you'd want `wlAddresses` to be `['23', '24', '25]` and similar for the others? – loganfsmyth Nov 08 '17 at 19:19
  • yes exactly without having to map for each property on its own @loganfsmyth – Moe Elsharif Nov 08 '17 at 19:23
  • What is your initial array of objects? – marciojc Nov 08 '17 at 19:26
  • @marciojc a csv file that is parsed which I think doesn't matter for this case because its a classic case of syntax and destructure – Moe Elsharif Nov 08 '17 at 19:27
  • But why do you want to use destructuring here? – kind user Nov 08 '17 at 19:30
  • Personally I think doing it with a `.map` would be the easiest approach. Destructuring does not solve this problem. – loganfsmyth Nov 08 '17 at 19:36
  • 1
    Can you clearly indicate at Question that the requirement is to use destructuring assignment only and not to use loops? See https://stackoverflow.com/help/how-to-ask. What code have you tried to use only destructuring to populate N arrays at the same assignment? – guest271314 Nov 08 '17 at 19:45
  • This cannot be done with restructuring only. A loop is required. There is no restructuring feature that iterates an array, collecting one properties and builds a new array of only that property. That's what `.map()` is used for. – jfriend00 Nov 08 '17 at 19:57
  • @jfriend00 The requirement can be met using destructuring assignment alone. Setting aside OP's use of the term "elegant" – guest271314 Nov 08 '17 at 20:12
  • 1
    @guest271314 - Your answer is hardly what qualifies. Instead of a loop, you just repeated code over and over again. That's not what anyone is looking for here. – jfriend00 Nov 08 '17 at 20:15
  • @jfriend00 That is exactly what OP is looking for as to the actual requirement https://stackoverflow.com/questions/47187778/destructuring-an-array-of-objects-with-es6/47188207?noredirect=1#comment81325701_47188136 - if only to gather they they probably want to use a loop – guest271314 Nov 08 '17 at 20:17
  • @guest271314 - Good answers don't suggest bad ways to code (at least those aren't the answers I ever upvote or would ever use in my own code). I don't consider your destructuring solution a good way to code so it won't get my upvote. And, I don't consider a practical way to solve the problem either. – jfriend00 Nov 08 '17 at 20:18
  • @jfriend00 "good" and "bad" are relative. Provide exact requirement that OP alluded to, and an alternative option. By providing each possible solutions perhaps OP might be able to compare what they are asking for to the suggested code using loops that appeared before OP clarified their requirement. – guest271314 Nov 08 '17 at 20:19
  • _"Its just a question of can be done or not, I am not forcing an answer"_ Yes "can be done". Though you should probably be specific as to what you are expecting to be done, and under which specific parameters – guest271314 Nov 08 '17 at 20:58
  • I don't understand the reason for downvoting it's just a simple question if it can be done or not honestly this will make me next time think twice before asking. it was a simple question that didn't require this amount of debate – Moe Elsharif Nov 08 '17 at 20:59
  • Is your understanding of the topic worth whatever "vote" your inquiry receives from viewers? If, yes, you can ignore the "downvote", if at all possible. If not, then your inquiry will probably not be decidedly resolved, as you would have abandoned your actual question in the face of a "vote". The code will not write itself, nor will true understanding appear spontaneously that you can recognize as such without being aware of your lack of understanding. – guest271314 Nov 08 '17 at 21:01
  • @guest271314 that is not the case I am just surprised by how things are, I assumed this is an open community where you can ask questions openly and learn, yes if its an already asked question then I agree but I sense somehow with your hardcoded answer that you don't care about the idea of information and just want to prove a point. and that is not what I was looking for not expected – Moe Elsharif Nov 08 '17 at 21:03
  • SO is a privately owned corporation. The notion of an "open community" would not bar different perspectives, even if SO was an "open community". SO encourages "downvote", without reason even https://meta.stackoverflow.com/questions/356706/moderator-deleting-comments-by-op. _"but I sense somehow with your hardcoded answer that you don't care about the idea of information and just want to prove a point."_ Prove what point? That the requirement that you described can be met? It is up to you to decide if that pattern is actually what you are trying to achieve. What code did you have to compare? – guest271314 Nov 08 '17 at 21:08
  • @MoeElsharif _"I don't understand"_ Apparently the requirement does include using a loop. You should now understand that, yes? – guest271314 Nov 08 '17 at 21:13

3 Answers3

3

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)
Mark
  • 90,562
  • 7
  • 108
  • 148
  • Upvoting for a reasonable way to code. Trying to do it with only destructuring only leads to a mess. These is clear, clear, concise, easy-to-understand code. – jfriend00 Nov 08 '17 at 20:16
2

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));
kind user
  • 40,029
  • 7
  • 67
  • 77
0

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);
guest271314
  • 1
  • 15
  • 104
  • 177
  • 1
    Looks kinda complicated. Did you test it anyways? – kind user Nov 08 '17 at 19:33
  • The whole idea of nested loops is something i didn't want in the first place i was thinking of an elegant way to do this maybe an ec6 feature that is not there – Moe Elsharif Nov 08 '17 at 19:35
  • @MoeElsharif Yes, the requirement is possible using only destructing assignment, though will probably require the same amount of code or more to reach source of assignment at target. What do you mean by "elegant"? – guest271314 Nov 08 '17 at 19:38
  • @Kinduser Yes, tested code before posting. See stacksnippets at updated Answer – guest271314 Nov 08 '17 at 19:41
  • @MoeElsharif See updated post for solution using only destructuring assignment – guest271314 Nov 08 '17 at 20:07
  • 1
    @guest271314 Isn't it a hardcoded solution right now? – kind user Nov 08 '17 at 20:13
  • @Kinduser That is the requirement. OP cannot have it both ways. – guest271314 Nov 08 '17 at 20:13
  • @guest271314 Ah, okey. It's nice, but doesn't look very well :P – kind user Nov 08 '17 at 20:14
  • @Kinduser Have no sense of "doesn't look very well". That is based on perspective. The code at second approach can be reduced to a single `while` loop - though OP specifically stated that the requirement is to use destructuring assignment alone, without using a loop https://stackoverflow.com/questions/47187778/destructuring-an-array-of-objects-with-es6/47188207?noredirect=1#comment81325701_47188136, ignoring any inquiry into the term "elegant" – guest271314 Nov 08 '17 at 20:16
  • I would never use destructing in this way. Doesn't meet my criteria for "good code" and therefore would not recommend this to anyone. – jfriend00 Nov 08 '17 at 20:20
  • @jfriend00 "good code" is relative and entirely based on opinion. Are you referring to the first code snippet at Answer as well? How can you actually convince an individual that they do not want what they considered they wanted without demonstrating that sometime you get exactly what you ask for? The code at second snippet reflects what occurs at a loop – guest271314 Nov 08 '17 at 20:23
  • I meant the same as @jfriend00 did. Just didn't want to be too harsh – kind user Nov 08 '17 at 20:25
  • @Kinduser There is nothing on the interwebs that is "harsh". Individuals can turn off the computer at any time – guest271314 Nov 08 '17 at 20:27
  • Yes, good code is based on opinion as are upvotes and downvotes here. That's what this place is about. We voters express our opinion about answers we think are good and those which we do not. That's what I'm doing. I find your first code block fairly hard to follow too, though not the same issue as the second code block. – jfriend00 Nov 08 '17 at 20:27
  • @guest271314 I understand you. Anyways I like to be kind. – kind user Nov 08 '17 at 20:28
  • @jfriend00 Fair enough. Posted both solutions to meet OP's stated technical requirement. What OP decides to do next is up to OP, at least now they are aware of many options and opinions of those options which were created based on the perspective of the author of the code, and reflected in the opinions expressed by "vote" of individuals. Any viewer of any facts or subject matter is free to use what they can from the data or not use the data at all. – guest271314 Nov 08 '17 at 20:29
  • FWIW, I think the OP's whole question is flawed. To attempt to answer them literally, there is no good solution (which is perhaps the only real answer here). They really ought to just describe the problem and ask for the best way to solve it without such artificial limitations that attempts to force responses down a bad-code path. – jfriend00 Nov 08 '17 at 20:37
  • @jfriend00 Asking the correct question based on the audience is a challenge in and of itself. Not every individual is aware of the culture of SO https://meta.stackoverflow.com/questions/358902/suggestions-for-including-an-actual-programming-question-in-question-where-the-o. Try to help, the opinion varies between help and do not help as no individual can truly estimate what another individual is considering at any moment in time. – guest271314 Nov 08 '17 at 20:41
  • @jfriend00 Updated Answer to include `while` loop version of second code snippet for OP to further compare possible approaches – guest271314 Nov 08 '17 at 20:49