Skip to content

Commit 38e9a49

Browse files
committed
Update exercise for object-destructuring
1 parent 3df9a45 commit 38e9a49

File tree

8 files changed

+254
-141
lines changed

8 files changed

+254
-141
lines changed

concepts/object-destructuring/introduction.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,30 @@
22

33
JavaScript's object destructuring syntax is a concise way to extract properties from an object and assign them to distinct variables.
44

5-
In this example, each value in the `numberOfMoons` array is assigned to its corresponding planet:
5+
In this example, weather symbols are extracted from the object `weather`:
66

77
```javascript
8-
const numberOfMoons = { venus: 0, mars: 2, neptune: 14 };
8+
const weather = {
9+
sun: '☀️',
10+
sun_behind_small_cloud: '🌤️',
11+
sun_behind_cloud: '',
12+
sun_behind_large_cloud: '🌥️',
13+
sun_behind_rain_cloud: '🌦️',
14+
cloud: '☁️',
15+
cloud_with_rain: '🌧️',
16+
cloud_with_snow: '🌨️',
17+
cloud_with_lightning: '🌩️',
18+
cloud_with_lightning_and_rain: '⛈️',
19+
};
920

10-
const { venus, mars, neptune } = numberOfMoons;
21+
const { sun, cloud, cloud_with_lightning } = weather;
1122

12-
neptune;
13-
// => 14
23+
sun;
24+
// => '☀️'
25+
26+
cloud;
27+
// => '☁️'
28+
29+
cloud_with_lightning;
30+
// => '🌩️'
1431
```

exercises/concept/elyses-destructured-enchantments/.docs/hints.md

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,35 @@
22

33
## 1. Get the first card
44

5-
- [This article][destructuring_overview_resource] has a good overview of array destructuring. You can find an example of basic variable assignment in the 'Basic Array Destructuring' section.
5+
- [This article][mdn-destructuring] has a good overview of array destructuring. You can find an example of basic variable assignment in the 'Basic Array Destructuring' section.
66

77
## 2. Get the second card
88

99
- You can use placeholders to ignore one or more values in the array.
10-
- You can find an example [here][ignoring_some_values_resource].
10+
- You can find an example [on MDN][mdn-destructuring-ignore-value].
1111

12-
## 3. Swap the first two cards
12+
## 3. Swap the two cards
1313

1414
- It's possible to swap two values in a single destructuring expression.
15-
- You can find an example [here][swapping_variables_resource].
15+
- You can find an example [on MDN][mdn-destructuring-swapping].
1616

17-
## 4. Discard the top card
17+
## 4. Shift three cards around
1818

19-
- There is a [built-in][rest_operator_docs] operator that can be used to collect the remaining values in an array into a single variable.
20-
- You can find an example [here][rest_assignment_resource].
19+
- It's possible to change the position of three values in a single destructuring expression.
20+
- This is the same as swapping two values, but then with three (or more).
2121

22-
## 5. Insert face cards
22+
## 5. Pick named pile
2323

24-
- There is a [built-in][spread_operator_docs] operator that can be used to expand an array into a list.
25-
- You can find a more detailed overview [here][spread_operator_overview].
24+
- Objects can be destructured just like arrays.
25+
- You can find an example [on MDN][mdn-object-destructuring-basic-assignment].
2626

27-
[destructuring_overview_resource]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Basic_variable_assignment
28-
[ignoring_some_values_resource]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Ignoring_some_returned_values
29-
[swapping_variables_resource]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Swapping_variables
30-
[rest_operator_docs]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Rest_syntax_parameters
31-
[rest_assignment_resource]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assigning_the_rest_of_an_array_to_a_variable
32-
[spread_operator_docs]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
33-
[spread_operator_overview]: https://blog.alexdevero.com/javascript-spread-operator
27+
## 6. Swap named piles
28+
29+
- When a property is extracted from an object, it can be renamed using specific syntax.
30+
- You can find an example [on MDN][mdn-object-destructuring-object-rename].
31+
32+
[mdn-destructuring]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Basic_variable_assignment
33+
[mdn-destructuring-ignore-value]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Ignoring_some_returned_values
34+
[mdn-destructuring-swapping]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Swapping_variables
35+
[mdn-object-destructuring-basic-assignment]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring#basic_assignment
36+
[mdn-object-destructuring-object-rename]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring#assigning_to_new_variable_names
Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,29 @@
11
# Instructions
22

3-
Elyse, magician-to-be, continues her training. She has a deck of cards she wants to manipulate.
3+
Elyse, magician-to-be, continues her training.
4+
She has a deck of cards she wants to manipulate.
45

5-
To make things easier, she usually only starts with cards numbered 1 to 10, although some of the tricks may involve additional cards.
6+
To make things easier, she usually only starts with cards numbered 2 to 10, although some of the tricks may involve additional (face) cards.
7+
8+
<!-- prettier-ignore-start -->
9+
~~~~exercism/note
10+
There are **many** ways to shuffle the cards around, but to keep up the illusion of magic, it is vital that *no single method is used*, e.g. Elyse doesn't use `splice`, `slice`, `shift`, `unshift`, `push`, `at`.
11+
The array accessor `array[index]` and object accessor (`object[key]` and `object.key`) are also never to be used.
12+
~~~~
13+
<!-- prettier-ignore-end -->
14+
15+
Want to level up Elyse her magic?
16+
17+
<!-- prettier-ignore-start -->
18+
~~~~exercism/advanced
19+
Every function can be implemented using the parameters and a function body with a single `return expression`.
20+
~~~~
21+
<!-- prettier-ignore-end -->
622

723
## 1. Get the first card
824

9-
Elyse will summon the first card in the deck without using the `array[index]` or `.shift()`. It's just like magic.
25+
Elyse will summon the first card in the deck without using the `array[index]`, `.at(index)`, or `.shift()`.
26+
It's just like magic.
1027

1128
```javascript
1229
const deck = [5, 9, 7, 1, 8];
@@ -17,7 +34,7 @@ getFirstCard(deck);
1734

1835
## 2. Get the second card
1936

20-
Elyse performs sleight of hand and summons the second card in the deck without using the `array[index]`.
37+
Elyse performs sleight of hand and summons the second card in the deck without using the `array[index]` or `.shift()`.
2138

2239
```javascript
2340
const deck = [3, 2, 10, 6, 7];
@@ -26,35 +43,56 @@ getSecondCard(deck);
2643
// => 2
2744
```
2845

29-
## 3. Swap the first two cards
46+
## 3. Swap two cards
47+
48+
Elyse will make the two cards of the deck switch places.
49+
She doesn't need to call a single function.
50+
51+
```javascript
52+
const deck = [10, 7];
53+
54+
swapTwoCards(deck);
55+
// => [7, 10]
56+
```
57+
58+
## 4. Shift three cards around
3059

31-
Elyse will make the top two cards of the deck switch places. She doesn't need to call a single function.
60+
In order to perform some more sleight of hand, Elyse takes three cards and quickly moves the top card to the back, making the middle card the first card and the old bottom card the middle card.
61+
She doesn't need to call a single function.
3262

3363
```javascript
34-
const deck = [10, 7, 3, 8, 5];
64+
const deck = [2, 6, 10];
3565

36-
swapTopTwoCards(deck);
37-
// => [7, 10, 3, 8, 5]
66+
shiftThreeCardsAround(deck);
67+
// => [6, 10, 2]
3868
```
3969

40-
## 4. Discard the top card
70+
## 5. Pick the named pile
4171

42-
Elyse will separate the deck into two piles. The first pile will contain only the top card of the original deck, while the second pile will contain all the other cards.
72+
Elyse will separate the deck into two piles.
73+
She then asks the observer to pick one of the two piles, which we'll name `chosen`.
74+
The `disregarded` pile is no longer relevant, which she makes disappear.
75+
She doesn't need to call a single function.
4376

4477
```javascript
45-
const deck = [2, 5, 4, 9, 3];
78+
const deck = [5, 4, 7, 10];
79+
const chosen = [5, 4];
80+
const disregarded = [7, 10];
4681

47-
discardTopCard(deck);
48-
// => [2, [5, 4, 9, 3]]
82+
pickNamedPile({ chosen, disregarded });
83+
// => [5, 4]
4984
```
5085

51-
## 5. Insert face cards
86+
## 5. Swap the picked pile
5287

53-
Elyse will insert a set of face cards (i.e. jack, queen, and king) into her deck such that they become the second, third, and fourth cards, respectively.
88+
Unfortunately the observer keeps picking the "wrong" pile, but with some clever fast magic, Elyse renames the `chosen` pile to be `disregarded` and the `disregarded` pile to be the `chosen` pile.
89+
She doesn't need to call a single function.
5490

5591
```javascript
5692
const deck = [5, 4, 7, 10];
93+
const chosen = [5, 4];
94+
const disregarded = [7, 10];
5795

58-
insertFaceCards(deck);
59-
// => [5, 'jack', 'queen', 'king', 4, 7, 10]
96+
swapNamedPile({ chosen, disregarded });
97+
// => { chosen: [7, 10], disregarded: [5, 4] }
6098
```

exercises/concept/elyses-destructured-enchantments/.docs/introduction.md

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,45 @@ neptune;
1414
// => 14
1515
```
1616

17-
## Rest and spread
17+
In short:
1818

19-
JavaScript has a built-in `...` operator that makes it easier to work with indefinite numbers of elements. Depending on the context, it's called either a _rest operator_ or _spread operator_.
19+
- The syntax allows for naming _positioned_ elements in an array, as well as swapping variables using re-assignment.
20+
- Destructuring syntax is available inside function parameters, and is available on any iterable.
21+
- Leaving a position unnamed (by not writing _any_ variable name) silently ignores that position.
2022

21-
### Rest elements
23+
## Object destructuring
2224

23-
When `...` appears on the left-hand side of an assignment, those three dots are known as the `rest` operator. The three dots together with a variable name is called a rest element. It collects zero or more values, and stores them into a single array.
25+
In JavaScript, there is also destructuring syntax to extract properties from an object and assign them to distinct variables.
2426

25-
```javascript
26-
const [a, b, ...everythingElse] = [0, 1, 1, 2, 3, 5, 8];
27+
In this example, weather symbols are extracted from the object `weather`:
2728

28-
everythingElse;
29-
// => [1, 2, 3, 5, 8]
29+
```javascript
30+
const weather = {
31+
sun: '☀️',
32+
sun_behind_small_cloud: '🌤️',
33+
sun_behind_cloud: '',
34+
sun_behind_large_cloud: '🌥️',
35+
sun_behind_rain_cloud: '🌦️',
36+
cloud: '☁️',
37+
cloud_with_rain: '🌧️',
38+
cloud_with_snow: '🌨️',
39+
cloud_with_lightning: '🌩️',
40+
cloud_with_lightning_and_rain: '⛈️',
41+
};
42+
43+
const { sun, cloud, cloud_with_lightning: thunder } = weather;
44+
45+
sun;
46+
// => '☀️'
47+
48+
cloud;
49+
// => '☁️'
50+
51+
thunder;
52+
// => '🌩️'
3053
```
3154

32-
Note that in JavaScript, unlike some other languages, a `rest` element cannot have a trailing comma. It _must_ be the last element in a destructuring assignment.
33-
34-
### Spread elements
35-
36-
When `...` appears on the right-hand side of an assignment, it's known as the `spread` operator. It expands an array into a list of elements. Unlike the rest element, it can appear anywhere in an array literal expression, and there can be more than one.
55+
In short:
3756

38-
```javascript
39-
const oneToFive = [1, 2, 3, 4, 5];
40-
const oneToTen = [...oneToFive, 6, 7, 8, 9, 10];
41-
42-
oneToTen;
43-
// => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
44-
```
57+
- The syntax allows for both extracting properties as well as extracting and renaming them.
58+
- Destructuring syntax is available inside function parameters.

exercises/concept/elyses-destructured-enchantments/.meta/design.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,19 @@
44

55
- Using destructuring to get the first item of an array
66
- Using destructuring to get the second item of an array (skip hole)
7-
- Using destructuring + rest elements to get the last item of an array
87
- Using destructuring to get the first two items of an array
9-
- Using destructuring + rest elements to get the head and tail of an array
10-
- Using spread to turn an array into a list of parameters
11-
- Using rest elements to turn a list of parameters into an array
128
- Using destructuring to swap two values
9+
- Using destructuring to extract properties from an object
10+
- Using destructuring to extract properties from an object and rename them
1311

1412
## Out of scope
1513

16-
- Anything with objects
1714
- Default values
1815

1916
## Concepts
2017

2118
- `array-destructuring`
22-
- `rest-and-spread`
19+
- `object-destructuring`
2320

2421
## Prerequisites
2522

exercises/concept/elyses-destructured-enchantments/.meta/exemplar.js

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,39 +24,46 @@ export function getSecondCard([, second]) {
2424
}
2525

2626
/**
27-
* Switch the position of the first two cards in the given deck
27+
* Switch the position of the two cards
2828
*
29-
* @param {Card[]} deck
29+
* @param {[Card, Card]} deck
3030
*
31-
* @returns {Card[]} new deck with reordered cards
31+
* @returns {[Card, Card]} new deck with the 2 cards swapped
3232
*/
33-
export function swapTopTwoCards([a, b, ...rest]) {
34-
return [b, a, ...rest];
33+
export function swapTwoCards([a, b]) {
34+
return [b, a];
3535
}
3636

3737
/**
38-
* Put the top card of the given deck into a separate discard pile
38+
* Rotate (shift) the position of the three cards (by one place)
3939
*
40-
* @param {Card[]} deck
40+
* @param {[Card, Card, Card]} deck
4141
*
42-
* @returns {[Card, Card[]]} the top card of the given
43-
* deck and a new deck containing all the other cards
42+
* @returns {[Card, Card, Card]} new deck with the 3 cards shifted by one position
4443
*/
45-
export function discardTopCard([first, ...rest]) {
46-
return [first, rest];
44+
export function shiftThreeCardsAround([a, b, c]) {
45+
return [b, c, a];
4746
}
4847

49-
/** @type Card[] **/
50-
const FACE_CARDS = ['jack', 'queen', 'king'];
51-
5248
/**
53-
* Insert face cards into the given deck
49+
* Grab the chosen pile from the available piles
5450
*
55-
* @param {Card[]} deck
51+
* @param {{ chosen: Card[], disregarded: Card[] }} piles
52+
*
53+
* @returns {Card[]} the pile named chosen
54+
*/
55+
export function pickNamedPile({ chosen }) {
56+
return chosen;
57+
}
58+
59+
/**
60+
* Swap the chosen pile for the disregarded pile and the disregarded pile for the chosen pile
5661
*
57-
* @returns {Card[]} new deck where the second,
58-
* third, and fourth cards are the face cards
62+
* @param {{ chosen: Card[], disregarded: Card[] }} piles
63+
* @returns {{ chosen: Card[], disregarded: Card[] }} new piles where the two piles are swapped
5964
*/
60-
export function insertFaceCards([head, ...tail]) {
61-
return [head, ...FACE_CARDS, ...tail];
65+
export function swapNamedPile({ chosen: disregarded, disregarded: chosen }) {
66+
// 🪄 Don't break the magic.
67+
// Do NOT touch the next line or Elyse will accidentally reveal the trick.
68+
return { chosen, disregarded };
6269
}

0 commit comments

Comments
 (0)