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

20
  • You will create a const variables which cannot be overwritten. Commented Nov 8, 2017 at 19:14
  • Are you saying you'd want wlAddresses to be ['23', '24', '25] and similar for the others? Commented Nov 8, 2017 at 19:19
  • yes exactly without having to map for each property on its own @loganfsmyth Commented Nov 8, 2017 at 19:23
  • 1
    Can you clearly indicate at Question that the requirement is to use destructuring assignment only and not to use loops? See stackoverflow.com/help/how-to-ask. What code have you tried to use only destructuring to populate N arrays at the same assignment? Commented Nov 8, 2017 at 19:45
  • 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. Commented Nov 8, 2017 at 20:15

4 Answers 4

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)

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

1 Comment

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.
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));

7 Comments

This is not the solution i was looking for i know that it can be done with mapping
@MoeElsharif Your actual question does not make it clear that requirement is to not use loops to achieve expected result.
@guest271314 I highly doubt that it's achievable without loops.
@Kinduser Yes, the requirement is achievable without using loops.
@guest271314 Then why have you posted a solution which has two loops?
|
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);

19 Comments

Looks kinda complicated. Did you test it anyways?
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
@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"?
@Kinduser Yes, tested code before posting. See stacksnippets at updated Answer
@guest271314 Isn't it a hardcoded solution right now?
|
0

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.)

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.