-2

trying to get better grasp on destructuring.
If I have object like this:

const starWars = {
  count: 2,
  data: [
   {name: 'Luke Skywalker', films: ['Empire Strikes Back', 'The Force Awakens']}, 
   {name: 'Han Solo', films: ['New Hope', 'Return of the Jedi']}
  ]};  

I can destructure data part like this:

const {data: allCharMovies} = starWars;
console.log(allCharMovies[1].name);  

or I can try to do:

const { count, data: [{name: nameCh, films: movies}]} = starWars;
console.log(nameCh, movies[1]);   

But but that only gives my movies for "Luke Skywalker" - how can I access "Han Solo" part if I do it the second way?

Tom N
  • 51
  • 9
  • You can't. You are only extracting the first array element. Destructuring is not suitable for extracting a variable number of values, just like you usually don't declare variables dynamically. – Felix Kling Sep 15 '20 at 09:24
  • 1
    You need to use `map` on the `data` array: `starWars.data.map(s => s.name)`. You can't do it just with destructuring . – adiga Sep 15 '20 at 09:30
  • So hmmm - I can extract array of objects into variable (allCharMovies) as long as I do not give that "receiving" array any structure. Otherwise if it has a structure - in second case - I can only point it at first element of array. OK - thanks - I am new to Javascript - just trying to understand basics. – Tom N Sep 15 '20 at 09:30
  • 1
    *"I can only point it at first element of array"* No, you can extract any number of array elements. But you can't do that dynamically. For example this extracts the name of the first two elements: `const {data: [{name: name1}, {name: name2}]} = starWars;`. Either way, destructuring doesn't seem useful for what you are trying to do. – Felix Kling Sep 15 '20 at 09:34
  • Thanks Felix - it is a class example. I literally started on JS yesterday. – Tom N Sep 15 '20 at 09:43

1 Answers1

1

You can add another object destructuring in the array while destructuring data:

const starWars = {
  count: 2,
  data: [
    { name: 'Luke Skywalker', films: ['Empire Strikes Back', 'The Force Awakens'] },
    { name: 'Han Solo', films: ['New Hope', 'Return of the Jedi'] }
  ]
};


const {
  count,
  data: [
    { name: nameCh, films: movies },
    { name: name2, films: movies2 }
  ]
} = starWars;

console.log(nameCh, movies[1]);
console.log(name2, movies2[1]);

Also, you can use the rest syntax to get all the movies except the first one:

const starWars = {
  count: 2,
  data: [
    { name: 'Luke Skywalker', films: ['Empire Strikes Back', 'The Force Awakens'] },
    { name: 'Han Solo', films: ['New Hope', 'Return of the Jedi'] },
    { name: 'Chewbacca', films: ['New Hope', 'The Force Awakens', 'The Last Jedi'] }
  ]
};


const { count, data: [{ name: nameCh, films: movies }, ...otherMovies] } = starWars;

console.log(nameCh, movies[1]);
console.log(otherMovies[0].name, otherMovies[0].films[1]);
console.log(otherMovies[1].name, otherMovies[1].films[2]);
Hao Wu
  • 17,573
  • 6
  • 28
  • 60
  • Yes of course - but what if I want Chewbacca and R2D2 too? (referring to first example). And in second case I lose ability to reference 'nameCh' and 'movies' with the 'rest' part - I can only use the 'name' and 'films'. – Tom N Sep 15 '20 at 09:34
  • Thanks Hao - I did - I just though that perhaps there is a way to combine the two. – Tom N Sep 15 '20 at 09:39
  • 1
    Well, you can keep destructuring `otherMovies` like destructuring a normal array... but destructuring this deep is not recommended, which makes your code much harder to read. – Hao Wu Sep 15 '20 at 09:42