mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-03-25 14:01:44 -04:00
feat(curriculum): add Space Mission Roster Workshop - JavaScript v9 (#64915)
Co-authored-by: majestic-owl448 <26656284+majestic-owl448@users.noreply.github.com> Co-authored-by: LGH831 <luishernandez1@csumb.edu>
This commit is contained in:
@@ -2923,6 +2923,12 @@
|
||||
"In this workshop, you'll review how to work with JavaScript loops by building a sentence analyzer app."
|
||||
]
|
||||
},
|
||||
"workshop-space-mission-roster": {
|
||||
"title": "Build a Space Mission Roster",
|
||||
"intro": [
|
||||
"In this workshop, you'll leverage JavaScript loops to build a space mission roster."
|
||||
]
|
||||
},
|
||||
"lab-longest-word-in-a-string": {
|
||||
"title": "Build a Longest Word Finder App",
|
||||
"intro": [
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
id: 694c40d86fe6a78d20b6559c
|
||||
title: Step 1
|
||||
challengeType: 1
|
||||
dashedName: step-1
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this workshop, you will leverage JavaScript to build a roster of astronauts for a space mission.
|
||||
|
||||
To begin, create an empty array for your roster named `squad`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create a `squad` variable.
|
||||
|
||||
```js
|
||||
assert.isDefined(squad);
|
||||
```
|
||||
|
||||
Your `squad` variable should be an array.
|
||||
|
||||
```js
|
||||
assert.isArray(squad);
|
||||
```
|
||||
|
||||
Your `squad` array should be empty.
|
||||
|
||||
```js
|
||||
assert.deepEqual(squad, []);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
id: 694c84106e9023f289c03b84
|
||||
title: Step 2
|
||||
challengeType: 1
|
||||
dashedName: step-2
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Your roster begins with a single commander astronaut. Create an object named `firstAstronaut` with the following properties:
|
||||
|
||||
| Key | Value |
|
||||
| ----------- | ------- |
|
||||
|`id`|`1`|
|
||||
|`name`|`"Andy"`|
|
||||
|`role`|`"Commander"`|
|
||||
|`isEVAEligible`|`true`|
|
||||
|`priority`|`3`|
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create a `firstAstronaut` variable.
|
||||
|
||||
```js
|
||||
assert.isDefined(firstAstronaut);
|
||||
```
|
||||
|
||||
Your `firstAstronaut` should be an object.
|
||||
|
||||
```js
|
||||
assert.isObject(firstAstronaut);
|
||||
```
|
||||
|
||||
Your `firstAstronaut` object should include the correct property values.
|
||||
|
||||
```js
|
||||
assert.deepEqual(firstAstronaut, { id: 1, name: "Andy", role: "Commander", isEVAEligible: true, priority: 3 });
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
id: 694c84330cbe604821b9deef
|
||||
title: Step 3
|
||||
challengeType: 1
|
||||
dashedName: step-3
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Mission control requires a method for adding new members to the roster. Create an empty function named `addCrewMember` that accepts two parameters, `crew` and `astronaut`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create a function named `addCrewMember`.
|
||||
|
||||
```js
|
||||
assert.isFunction(addCrewMember);
|
||||
```
|
||||
|
||||
Your `addCrewMember` function should have parameters `crew` and `astronaut`.
|
||||
|
||||
```js
|
||||
const regex = __helpers.functionRegex('addCrewMember', ['crew', 'astronaut']);
|
||||
assert.match(__helpers.removeJSComments(addCrewMember.toString()), regex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
id: 694c9c186c089f7bdff0f3c6
|
||||
title: Step 4
|
||||
challengeType: 1
|
||||
dashedName: step-4
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Generally, it is good practice to validate your input(s) inside a function. Use a `for` loop to iterate through the `crew` array and check whether any member already has the same `id` as the input `astronaut`. If a duplicate is found, log the error message `console.log("Duplicate ID: " + astronaut.id)` and then call `return` to exit the function early.
|
||||
|
||||
Here is an example of this commonly used technique:
|
||||
|
||||
```js
|
||||
if (existingMember.id === newMember.id) {
|
||||
console.log("Duplicate ID: " + newMember.id);
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
Your function should use a `for` loop to scan existing `crew` members (any valid `for (...)` form is fine).
|
||||
|
||||
```js
|
||||
assert.match(__helpers.removeJSComments(code), /for\s*\([^)]*\)/);
|
||||
```
|
||||
|
||||
Inside the `for` loop, you should check for a duplicate `id`. If one is found, log `"Duplicate ID: " + astronaut.id"` to the console and then call `return` to exit the function.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(console, "log");
|
||||
|
||||
try {
|
||||
const crewWithDuplicate = [
|
||||
{ id: 1 },
|
||||
{ id: 2 },
|
||||
{ id: 3 },
|
||||
{ id: 4 },
|
||||
{ id: 3 }
|
||||
];
|
||||
addCrewMember(crewWithDuplicate, { id: 3 });
|
||||
|
||||
assert.lengthOf(
|
||||
spy.calls,
|
||||
1,
|
||||
"Duplicate ID input should trigger exactly one console.log and then exit"
|
||||
);
|
||||
assert.match(
|
||||
spy.calls[0][0],
|
||||
/duplicate\s+id\s*:\s*3/i,
|
||||
"Console message should mention 'duplicate id'"
|
||||
);
|
||||
|
||||
} catch (err) {
|
||||
assert.fail(err);
|
||||
} finally {
|
||||
spy.restore();
|
||||
}
|
||||
```
|
||||
|
||||
When given valid inputs, your `addCrewMember` function should not invoke a `console.log()` error message or an early `return` exit.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(console, "log");
|
||||
|
||||
try {
|
||||
const crewNoDuplicate = [
|
||||
{ id: 1 },
|
||||
{ id: 2 },
|
||||
{ id: 3 },
|
||||
{ id: 4 }
|
||||
];
|
||||
addCrewMember(crewNoDuplicate, { id: 5 });
|
||||
|
||||
assert.lengthOf(
|
||||
spy.calls,
|
||||
0,
|
||||
"A truly new astronaut should produce zero console.log calls"
|
||||
);
|
||||
|
||||
} catch (err) {
|
||||
assert.fail(err);
|
||||
} finally {
|
||||
spy.restore();
|
||||
}
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,99 @@
|
||||
---
|
||||
id: 694ca14c8ef00056ad146e51
|
||||
title: Step 5
|
||||
challengeType: 1
|
||||
dashedName: step-5
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Push the `astronaut` object into the `crew` array and log `Added ${astronaut.name} as ${astronaut.role}` to the console. You can use either template literals or string concatenation for the log message.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should push the `astronaut` into the `crew` array.
|
||||
|
||||
```js
|
||||
const crew = [];
|
||||
const astronauts = [
|
||||
{ id: 1, name: "Abraham", role: "Commander", isEVAEligible: true, priority: 1 },
|
||||
{ id: 2, name: "Boris", role: "Pilot", isEVAEligible: false, priority: 2 },
|
||||
{ id: 3, name: "Catarina", role: "Engineer", isEVAEligible: true, priority: 3 }
|
||||
];
|
||||
|
||||
astronauts.forEach(astro => addCrewMember(crew, astro));
|
||||
|
||||
assert.strictEqual(crew.length, astronauts.length);
|
||||
astronauts.forEach((astro, idx) => {
|
||||
assert.deepEqual(crew[idx], astro);
|
||||
});
|
||||
```
|
||||
|
||||
You should log the astronaut's `name` in the following format, `Added {astronaut.name} as {astronaut.role}`.
|
||||
|
||||
```js
|
||||
function captureConsoleLogs(fn) {
|
||||
const originalLog = console.log;
|
||||
const logs = [];
|
||||
|
||||
console.log = function (...args) {
|
||||
logs.push(args.join(" "));
|
||||
};
|
||||
|
||||
try {
|
||||
fn();
|
||||
} finally {
|
||||
console.log = originalLog;
|
||||
}
|
||||
|
||||
return logs;
|
||||
}
|
||||
|
||||
const crewForLogging = [];
|
||||
const astronautsToLog = [
|
||||
{ id: 1, name: "Abraham", role: "Commander" },
|
||||
{ id: 2, name: "Boris", role: "Pilot" },
|
||||
{ id: 3, name: "Catarina", role: "Engineer" }
|
||||
];
|
||||
|
||||
const logs = captureConsoleLogs(() => {
|
||||
astronautsToLog.forEach(astro => addCrewMember(crewForLogging, astro));
|
||||
});
|
||||
|
||||
assert.strictEqual(logs.length, astronautsToLog.length);
|
||||
|
||||
astronautsToLog.forEach((astro, idx) => {
|
||||
assert.match(
|
||||
logs[idx],
|
||||
new RegExp(`Added\\s*${astro.name}\\s*as\\s*${astro.role}`, 'i'),
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
id: 694cabb9f1afa9446f36ffc0
|
||||
title: Step 6
|
||||
challengeType: 1
|
||||
dashedName: step-6
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now you can start building your roster. Use `addCrewMember()` to add the `firstAstronaut` to your `squad`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call `addCrewMember()` with `squad` and `firstAstronaut`.
|
||||
|
||||
```js
|
||||
assert.match(__helpers.removeJSComments(code), /addCrewMember\s*\(\s*squad\s*,\s*firstAstronaut\s*\)/);
|
||||
assert.strictEqual(squad.length, 1);
|
||||
assert.strictEqual(squad[0], firstAstronaut);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
console.log(`Added ${astronaut.name} as ${astronaut.role}`);
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
id: 694cada4bc0242600b5f21ea
|
||||
title: Step 7
|
||||
challengeType: 1
|
||||
dashedName: step-7
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The rest of your crew has been created in an array named `remainingCrew` with the following data:
|
||||
|
||||
| id | name | role | isEVAEligible | priority |
|
||||
| -- | ---- | ---- | ------------- | -------- |
|
||||
|`2`|`"Bart"`|`"Pilot"`|`false`|`8`|
|
||||
|`3`|`"Caroline"`|`"Engineer"`|`true`|`4`|
|
||||
|`4`|`"Diego"`|`"Scientist"`|`false`|`1`|
|
||||
|`5`|`"Elise"`|`"Medic"`|`true`|`7`|
|
||||
|`6`|`"Felix"`|`"Navigator"`|`true`|`6`|
|
||||
|`7`|`"Gertrude"`|`"Communications"`|`false`|`4`|
|
||||
|`8`|`"Hank"`|`"Mechanic"`|`true`|`2`|
|
||||
|`9`|`"Irene"`|`"Specialist"`|`true`|`5`|
|
||||
|`10`|`"Joan"`|`"Technician"`|`false`|`1`|
|
||||
|
||||
Loop through the `remainingCrew` array and add each astronaut to `squad` using the `addCrewMember()` function.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use a `for` loop to call `addCrewMember()` with each astronaut in `remainingCrew`.
|
||||
|
||||
```js
|
||||
const matches = (__helpers.removeJSComments(code).match(/addCrewMember\s*\(\s*squad[^)]*\)/g)) || [];
|
||||
assert.isAtLeast(matches.length, 2);
|
||||
assert.strictEqual(squad.length, 10);
|
||||
assert.strictEqual(squad[0].id, 1);
|
||||
assert.strictEqual(squad[9].id, 10);
|
||||
assert.strictEqual(squad[8].name, "Irene");
|
||||
assert.strictEqual(squad[7].role, "Mechanic");
|
||||
assert.strictEqual(squad[5].priority, 6);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
console.log(`Added ${astronaut.name} as ${astronaut.role}`);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
id: 694ce8609fb805ba21cebc02
|
||||
title: Step 9
|
||||
challengeType: 1
|
||||
dashedName: step-9
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Mission control needs a method to swap the positions of two crew members in a roster. Create an empty function named `swapCrewMembers` with three parameters:
|
||||
|
||||
- `crew`: an array of astronaut objects
|
||||
|
||||
- `fromIndex`: the index of the first astronaut to swap
|
||||
|
||||
- `toIndex`: the index of the second astronaut to swap
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create a function named `swapCrewMembers`.
|
||||
|
||||
```js
|
||||
assert.isFunction(swapCrewMembers);
|
||||
```
|
||||
|
||||
Your `swapCrewMembers` function should have parameters `crew`, `fromIndex`, and `toIndex`.
|
||||
|
||||
```js
|
||||
const regex = __helpers.functionRegex('swapCrewMembers', ['crew', 'fromIndex', 'toIndex']);
|
||||
assert.match(__helpers.removeJSComments(swapCrewMembers.toString()), regex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,185 @@
|
||||
---
|
||||
id: 694d8c16f3672c498d4656ac
|
||||
title: Step 10
|
||||
challengeType: 1
|
||||
dashedName: step-10
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
As before, start by validating the input inside the `swapCrewMembers` function. Specifically, you must validate the indices of the astronauts to be swapped.
|
||||
|
||||
If any of the following are true:
|
||||
|
||||
- `fromIndex` is negative
|
||||
|
||||
- `fromIndex` is greater than or equal to `crew.length`
|
||||
|
||||
- `toIndex` is negative
|
||||
|
||||
- `toIndex` is greater than or equal to `crew.length`
|
||||
|
||||
then, you should log `"Invalid crew indices"` to the console and call `return` to exit the function.
|
||||
|
||||
You can use the OR operator `||` to check multiple conditions at once:
|
||||
|
||||
```js
|
||||
if (condition1 || condition2 || condition3 || condition4) {
|
||||
console.log("Message");
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
You should validate indices using an `if` statement.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeJSComments(
|
||||
swapCrewMembers.toString()
|
||||
);
|
||||
assert.match(
|
||||
cleaned,
|
||||
/\bif\s*\([^)]*\)/,
|
||||
"Your function must use at least one if statement to validate indices"
|
||||
);
|
||||
```
|
||||
|
||||
You should first validate indices and, if invalid, log the message `"Invalid crew indices"` before exiting the function using `return`.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(console, "log");
|
||||
|
||||
try {
|
||||
const crew = [
|
||||
{ id: 1 },
|
||||
{ id: 2 },
|
||||
{ id: 3 },
|
||||
{ id: 4 },
|
||||
{ id: 5 }
|
||||
];
|
||||
swapCrewMembers(crew, -1, 2);
|
||||
swapCrewMembers(crew, 1, 10);
|
||||
swapCrewMembers(crew, 15, 3);
|
||||
swapCrewMembers(crew, -5, 99);
|
||||
swapCrewMembers(crew, 2, -1)
|
||||
swapCrewMembers(crew, 2, 3);
|
||||
assert.lengthOf(
|
||||
spy.calls,
|
||||
5,
|
||||
"Each invalid call should log exactly once"
|
||||
);
|
||||
spy.calls.forEach(call => {
|
||||
assert.match(
|
||||
call[0],
|
||||
/^Invalid crew indices$/i,
|
||||
"Each log must be 'Invalid crew indices'"
|
||||
);
|
||||
});
|
||||
} catch (err) {
|
||||
assert.fail(err);
|
||||
} finally {
|
||||
spy.restore();
|
||||
}
|
||||
```
|
||||
|
||||
Immediately after logging the message in the validation check, invoke `return` to exit the function early.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(swapCrewMembers.toString()));
|
||||
const logReturnRegex = /console\.log\s*\([^)]*\)\s*;\s*return\b/g;
|
||||
const matches = cleaned.match(logReturnRegex) || [];
|
||||
const allLogs = cleaned.match(/console\.log\s*\([^)]*\)/g) || [];
|
||||
assert.strictEqual(
|
||||
matches.length,
|
||||
allLogs.length,
|
||||
"Every console.log(...) must be immediately followed by return"
|
||||
);
|
||||
|
||||
const spy = __helpers.spyOn(console, "log");
|
||||
try {
|
||||
const source = __helpers.removeJSComments(swapCrewMembers.toString());
|
||||
const instrumentedSource = source.replace(/\}\s*$/, 'console.log("TEST"); }');
|
||||
const instrumentedFn = eval("(" + instrumentedSource + ")");
|
||||
instrumentedFn([{ id: 1 }, { id: 2 }], -1, 1);
|
||||
assert.lengthOf(spy.calls, 1);
|
||||
assert.match(spy.calls[0][0], /invalid\s+crew\s+indices/i);
|
||||
} finally {
|
||||
spy.restore();
|
||||
}
|
||||
```
|
||||
|
||||
When given valid inputs, your `swapCrewMembers` function should not log any error messages and should not exit early.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(console, "log");
|
||||
try {
|
||||
const crew = [
|
||||
{ id: 1 },
|
||||
{ id: 2 },
|
||||
{ id: 3 },
|
||||
{ id: 4 },
|
||||
{ id: 5 }
|
||||
];
|
||||
swapCrewMembers(crew, 1, 3);
|
||||
assert.lengthOf(
|
||||
spy.calls,
|
||||
0,
|
||||
"Valid indices should not trigger any console.log"
|
||||
);
|
||||
} catch (err) {
|
||||
assert.fail(err);
|
||||
} finally {
|
||||
spy.restore();
|
||||
}
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,92 @@
|
||||
---
|
||||
id: 694d8ddbfc4bb6940b921bbc
|
||||
title: Step 11
|
||||
challengeType: 1
|
||||
dashedName: step-11
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You should create a shallow copy of the `crew` array using the `slice()` method. Name the new array `updatedCrew`.
|
||||
|
||||
Recall that calling `slice()` without arguments returns a copy of the entire array:
|
||||
|
||||
```js
|
||||
const copyArray = originalArray.slice();
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use the `slice()` method to copy the input `crew` array and store the result in a new variable named `updatedCrew`.
|
||||
|
||||
```js
|
||||
const funcStr = __helpers.removeJSComments(swapCrewMembers.toString());
|
||||
assert.match(
|
||||
funcStr,
|
||||
/(var|let|const)\s+updatedCrew/,
|
||||
"You must have at least one space between the declaration keyword (let/const) and 'updatedCrew'"
|
||||
);
|
||||
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(swapCrewMembers.toString()));
|
||||
assert.match(cleaned, /(var|let|const)updatedCrew=crew\.slice\(\);?\}$/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,124 @@
|
||||
---
|
||||
id: 694d8ddd106340237efb0c80
|
||||
title: Step 12
|
||||
challengeType: 1
|
||||
dashedName: step-12
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The `splice()` method can modify arrays by adding or removing elements at any position, including the middle. Since `splice()` returns an array containing the removed elements, you can use it to swap two elements in an array without mutating the original. This can be done in one line using the following technique:
|
||||
|
||||
```js
|
||||
// swap elements at i and j without mutating the original
|
||||
const copy = array.slice();
|
||||
copy[i] = copy.splice(j, 1, copy[i])[0];
|
||||
```
|
||||
|
||||
Here is an example:
|
||||
|
||||
```js
|
||||
const originalArray = [12, 97, 68, 55];
|
||||
const copyArray = originalArray.slice();
|
||||
copyArray[1] = copyArray.splice(3, 1, copyArray[1])[0];
|
||||
console.log(copyArray); // [12, 55, 68, 97]
|
||||
```
|
||||
|
||||
The technique, applied in the third line, works as follows:
|
||||
|
||||
- `splice(3, 1, copyArray[1])` removes the element at index `3` (`55`)
|
||||
|
||||
- It inserts the element from `copyArray[1]` (`97`) into index `3`
|
||||
|
||||
- `splice()` returns `[55]`, an array containing the removed element
|
||||
|
||||
- `[0]` extracts `55` from that array
|
||||
|
||||
- That value (`55`) is assigned back to `copyArray[1]`, completing the swap
|
||||
|
||||
Use this technique with the `updatedCrew` array to swap the astronauts at `fromIndex` and `toIndex`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should perform the swap by calling the `splice()` method.
|
||||
|
||||
```js
|
||||
assert.match(swapCrewMembers.toString(), /splice\s*\(/);
|
||||
```
|
||||
|
||||
You should call `splice()` with the `updatedCrew` array to perform the swap. You should use the one-line technique.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(swapCrewMembers.toString()));
|
||||
const regex = /updatedCrew\[(fromIndex|toIndex)\]=updatedCrew\.splice\((fromIndex|toIndex),1,updatedCrew\[\1\]\)\[0\];?\s*\}$/;
|
||||
assert.match(cleaned, regex);
|
||||
```
|
||||
|
||||
Your `swapCrewMembers` function should not mutate the original input `crew` array.
|
||||
|
||||
```js
|
||||
const demo = [{ id: 1 }, { id: 2 }, { id: 3 }];
|
||||
swapCrewMembers(demo, 0, 2);
|
||||
assert.deepEqual(demo.map(a => a.id), [1, 2, 3]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,136 @@
|
||||
---
|
||||
id: 694d98a87c2a7a33ca92cfa9
|
||||
title: Step 13
|
||||
challengeType: 1
|
||||
dashedName: step-13
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Use a `for` loop to log the `name` of every astronaut in the `updatedCrew` array. After the loop, return the `updatedCrew` array to complete your `swapCrewMembers` function.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use a `for` loop to iterate through the `updatedCrew` array and log the `name` of each astronaut.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(swapCrewMembers.toString()));
|
||||
const loopAndLogRegex = /(?:for\([^)]*updatedCrew[^)]*\)[\s\S]*?console\.log\(|_createForOfIteratorHelper\(updatedCrew\)[\s\S]*?console\.log\()/;
|
||||
assert.match( cleaned, loopAndLogRegex, 'A for(...) loop over updatedCrew is required and console.log() must be inside the loop' );
|
||||
|
||||
function captureConsoleLogs(fn) {
|
||||
const originalLog = console.log;
|
||||
const logs = [];
|
||||
|
||||
console.log = function (...args) {
|
||||
logs.push(args.join(" "));
|
||||
};
|
||||
|
||||
try {
|
||||
fn();
|
||||
} finally {
|
||||
console.log = originalLog;
|
||||
}
|
||||
|
||||
return logs;
|
||||
}
|
||||
|
||||
const sample = [
|
||||
{ name: "A" },
|
||||
{ name: "B" },
|
||||
{ name: "C" }
|
||||
];
|
||||
|
||||
const logs = captureConsoleLogs(() =>
|
||||
swapCrewMembers(sample, 0, 2)
|
||||
);
|
||||
|
||||
const expectedOrder = ["C", "B", "A"];
|
||||
|
||||
assert.strictEqual(
|
||||
logs.length,
|
||||
expectedOrder.length,
|
||||
"You must log each astronaut's name exactly once"
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
logs,
|
||||
expectedOrder,
|
||||
"console.log must log each astronaut's .name in order"
|
||||
);
|
||||
```
|
||||
|
||||
You should return the `updatedCrew` array after logging its astronauts' names.
|
||||
|
||||
```js
|
||||
const sample = [
|
||||
{ name: "A" },
|
||||
{ name: "B" },
|
||||
{ name: "C" }
|
||||
];
|
||||
const result = swapCrewMembers(sample, 0, 2);
|
||||
assert.isArray(result);
|
||||
assert.deepEqual(result.map(a => a.name), ["C", "B", "A"]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,95 @@
|
||||
---
|
||||
id: 694dfd604c32cfe8e298784c
|
||||
title: Step 14
|
||||
challengeType: 1
|
||||
dashedName: step-14
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Mission control has requested you to swap the positions of two astronauts in your `squad` array, specifically members at indices `2` and `5`. Use your `swapCrewMembers()` function to perform the swap and store the result in a new variable named `updatedSquad`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use `swapCrewMembers()` to swap `squad` members at indices `2` and `5` and store the resulting array in a new variable named `updatedSquad`.
|
||||
|
||||
```js
|
||||
assert.match(
|
||||
__helpers.removeJSComments(code),
|
||||
/(let|const)\s+updatedSquad/,
|
||||
"You must have at least one space between the declaration keyword (let/const) and 'updatedSquad'"
|
||||
);
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(code));
|
||||
assert.match(cleaned, /(let|const)updatedSquad=swapCrewMembers\(squad,?(2,?5|5,?2)\)/);
|
||||
const result = [...updatedSquad];
|
||||
assert.strictEqual(result[2].name, "Felix");
|
||||
assert.strictEqual(result[5].name, "Caroline");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
for (let i = 0; i < updatedCrew.length; i++) {
|
||||
console.log(updatedCrew[i].name);
|
||||
}
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,92 @@
|
||||
---
|
||||
id: 694e0952a3742f2898aef517
|
||||
title: Step 16
|
||||
challengeType: 1
|
||||
dashedName: step-16
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Mission control requires a method for copying EVA-eligible astronauts from a crew. Create an empty function named `getEVAReadyCrew` that accepts a `crew` parameter.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create a function named `getEVAReadyCrew`.
|
||||
|
||||
```js
|
||||
assert.isFunction(getEVAReadyCrew);
|
||||
```
|
||||
|
||||
Your `getEVAReadyCrew` function should have a `crew` parameter.
|
||||
|
||||
```js
|
||||
const regex = __helpers.functionRegex('getEVAReadyCrew', ['crew']);
|
||||
assert.match(__helpers.removeJSComments(code), regex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,123 @@
|
||||
---
|
||||
id: 694e0c6e2cf8b9b45755f0f5
|
||||
title: Step 17
|
||||
challengeType: 1
|
||||
dashedName: step-17
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
First, create an empty array named `eligible`. Then loop through every astronaut in the input `crew` array and, if they are EVA-eligible (meaning their `isEVAEligible` property is `true`), push them into the `eligible` array. After the loop, return the `eligible` array.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create an array named `eligible`.
|
||||
|
||||
```js
|
||||
const funcStr = __helpers.removeJSComments(getEVAReadyCrew.toString());
|
||||
assert.match(
|
||||
funcStr,
|
||||
/(var|let|const)\s+eligible/,
|
||||
"You must have at least one space between the declaration keyword (let/const) and 'eligible'"
|
||||
);
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(getEVAReadyCrew.toString()));
|
||||
assert.match(cleaned, /(?:^|[^a-zA-Z])(var|let|const)eligible=\[\]/);
|
||||
```
|
||||
|
||||
You should use a `for` loop to iterate through the input `crew` array.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(getEVAReadyCrew.toString()));
|
||||
assert.match(cleaned, /for\s*\(/);
|
||||
```
|
||||
|
||||
You should return the `eligible` array.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(getEVAReadyCrew.toString()));
|
||||
assert.match(cleaned, /returneligible;?}$/);
|
||||
|
||||
const sample2 = [{ isEVAEligible: true }];
|
||||
assert.isArray(getEVAReadyCrew(sample2));
|
||||
```
|
||||
|
||||
After calling `getEVAReadyCrew()`, the returned array should contain only EVA-eligible astronauts from the input array `crew`.
|
||||
|
||||
```js
|
||||
const sample = [
|
||||
{ name: "A", isEVAEligible: true },
|
||||
{ name: "B", isEVAEligible: false },
|
||||
{ name: "C", isEVAEligible: true }
|
||||
];
|
||||
const result = getEVAReadyCrew(sample);
|
||||
assert.deepEqual(result.map(a => a.name), ["A", "C"]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,148 @@
|
||||
---
|
||||
id: 694e1931f6509ae16aa1c36f
|
||||
title: Step 18
|
||||
challengeType: 1
|
||||
dashedName: step-18
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Mission control has alerted you that the list of EVA-eligible astronauts should also be sorted by priority descending. There are a few ways to sort an array - perhaps the most basic is `bubble sort`.
|
||||
|
||||
`Bubble sort` works by repeatedly stepping through a list, comparing neighboring items, and swapping them if they’re in the wrong order. After each pass, the item that should come first based on your sort criteria moves closer to (or “bubbles” toward) its correct position in the array. Here is how you can sort `crew` by priority descending using `bubble sort`:
|
||||
|
||||
```js
|
||||
// Outer loop: controls how many passes we make
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
// Inner loop: compares neighboring items
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
// If current member has lower priority than next, swap
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
// Using a temp variable for the swap
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Create a new helper function named `sortByPriorityDescending` that accepts a `crew` parameter. This function should directly sort the input `crew` array by priority descending, use two nested `for` loops, and should not return anything.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a function named `sortByPriorityDescending` with a `crew` parameter.
|
||||
|
||||
```js
|
||||
assert.isFunction(sortByPriorityDescending);
|
||||
const regex = __helpers.functionRegex('sortByPriorityDescending', ['crew']);
|
||||
const cleaned = __helpers.removeJSComments(sortByPriorityDescending.toString());
|
||||
assert.match(cleaned, regex);
|
||||
```
|
||||
|
||||
Your `sortByPriorityDescending` function should use two nested `for` loops to perform the sort.
|
||||
|
||||
```js
|
||||
const loopMatches = sortByPriorityDescending.toString().match(/for\s*\(/g) || [];
|
||||
assert.isAtLeast(loopMatches.length, 2);
|
||||
```
|
||||
|
||||
Your `sortByPriorityDescending` function should sort the input `crew` by `priority` in descending order.
|
||||
|
||||
```js
|
||||
const crewSample = [
|
||||
{ name: "A", priority: 2 },
|
||||
{ name: "B", priority: 5 },
|
||||
{ name: "C", priority: 3 }
|
||||
];
|
||||
sortByPriorityDescending(crewSample);
|
||||
assert.deepEqual(crewSample.map(a => a.name), ["B", "C", "A"]);
|
||||
```
|
||||
|
||||
Your `sortByPriorityDescending` function should directly sort the input `crew` array in-place and not return a new array.
|
||||
|
||||
```js
|
||||
const crewSample2 = [
|
||||
{ name: "X", priority: 1 },
|
||||
{ name: "Y", priority: 2 }
|
||||
];
|
||||
const result = sortByPriorityDescending(crewSample2);
|
||||
assert.strictEqual(result, undefined);
|
||||
assert.deepEqual(crewSample2.map(a => a.priority), [2, 1]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
|
||||
return eligible;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,114 @@
|
||||
---
|
||||
id: 694eeb57faae3b2331add3e7
|
||||
title: Step 19
|
||||
challengeType: 1
|
||||
dashedName: step-19
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Back inside the `getEVAReadyCrew` function, call `sortByPriorityDescending()` with the local `eligible` array so that it is sorted before being returned.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call `sortByPriorityDescending()` with the local `eligible` array.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(getEVAReadyCrew.toString()));
|
||||
assert.match(cleaned, /(?:^|[^a-zA-Z])sortByPriorityDescending\(eligible\)/);
|
||||
const sample = [
|
||||
{ name: "Low", isEVAEligible: true, priority: 1 },
|
||||
{ name: "High", isEVAEligible: true, priority: 5 },
|
||||
{ name: "Mid", isEVAEligible: true, priority: 3 },
|
||||
{ name: "NoEVA", isEVAEligible: false, priority: 10 }
|
||||
];
|
||||
const result = getEVAReadyCrew(sample);
|
||||
assert.deepEqual(result.map(a => a.name), ["High", "Mid", "Low"]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
return eligible;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,149 @@
|
||||
---
|
||||
id: 694eef2a7aa196d5f4fa96b9
|
||||
title: Step 20
|
||||
challengeType: 1
|
||||
dashedName: step-20
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Invoke `getEVAReadyCrew()` with your `updatedSquad` roster and store the result in a new variable named `EVAReadySquad`. Then, use a `for` loop to log the `name` of every astronaut in the `EVAReadySquad` array.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call `getEVAReadyCrew()` with `updatedSquad` and store the result in a new variable named `EVAReadySquad`.
|
||||
|
||||
```js
|
||||
assert.match(
|
||||
__helpers.removeJSComments(code),
|
||||
/(let|const)\s+EVAReadySquad/,
|
||||
"You must have at least one space between the declaration keyword (let/const) and 'EVAReadySquad'"
|
||||
);
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(code));
|
||||
assert.match(cleaned, /(let|const)EVAReadySquad=getEVAReadyCrew\(updatedSquad\)/);
|
||||
assert.isArray(EVAReadySquad);
|
||||
assert.strictEqual(EVAReadySquad.length, 6)
|
||||
const EVANames = EVAReadySquad.map(a => a.name);
|
||||
assert.deepEqual(EVANames.slice(), ["Elise", "Felix", "Irene", "Caroline", "Andy", "Hank"]);
|
||||
```
|
||||
|
||||
You should use a `for` loop to iterate through the `EVAReadySquad` array and log the `name` of each astronaut.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeJSComments(code).replace(/\s+/g, "");
|
||||
assert.match(cleaned, /for\([^)]*EVAReadySquad[^)]*\)/, 'A for(...) loop over EVAReadySquad is required');
|
||||
assert.match(cleaned, /console\.log[^;]*\.name/, 'console.log should log the .name property');
|
||||
function captureConsoleFromCode(code) {
|
||||
const logs = [];
|
||||
const originalLog = console.log;
|
||||
console.log = (...args) => logs.push(args.join(" "));
|
||||
try {
|
||||
const userScriptFn = new Function(code);
|
||||
userScriptFn();
|
||||
} finally {
|
||||
console.log = originalLog;
|
||||
}
|
||||
return logs;
|
||||
}
|
||||
const logs = captureConsoleFromCode(code);
|
||||
const expectedNames = ["Elise", "Felix", "Irene", "Caroline", "Andy", "Hank"];
|
||||
assert.strictEqual(
|
||||
logs.length,
|
||||
expectedNames.length,
|
||||
"You must log each EVA-ready astronaut's name exactly once"
|
||||
);
|
||||
assert.deepEqual(
|
||||
logs,
|
||||
expectedNames,
|
||||
"console.log must log the .name property of each EVA-ready astronaut in order"
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
sortByPriorityDescending(eligible);
|
||||
|
||||
return eligible;
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,115 @@
|
||||
---
|
||||
id: 694f55431c34fe3ab17c482f
|
||||
title: Step 22
|
||||
challengeType: 1
|
||||
dashedName: step-22
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Mission control has requested a new function for breaking down a crew into chunks of variable sizes. Create an empty function named `chunkCrew` that accepts two parameters, `crew` and `size`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create a function named `chunkCrew`.
|
||||
|
||||
```js
|
||||
assert.isFunction(chunkCrew);
|
||||
```
|
||||
|
||||
Your `chunkCrew` function should have `crew` and `size` parameters.
|
||||
|
||||
```js
|
||||
const regex = __helpers.functionRegex('chunkCrew', ['crew', 'size']);
|
||||
assert.match(__helpers.removeJSComments(chunkCrew.toString()), regex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
sortByPriorityDescending(eligible);
|
||||
return eligible;
|
||||
}
|
||||
|
||||
const EVAReadySquad = getEVAReadyCrew(updatedSquad);
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,187 @@
|
||||
---
|
||||
id: 694f7cae8b5aa1f91cb33c8b
|
||||
title: Step 23
|
||||
challengeType: 1
|
||||
dashedName: step-23
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
As before, you should validate your input. Specifically, if `size` is less than `1`, you should log `"Chunk size must be >= 1"` to the console and then call `return` to exit the function.
|
||||
|
||||
# --hints--
|
||||
|
||||
If the input `size` is invalid, you should log the following error message to the console, `"Chunk size must be >= 1"`.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(console, "log");
|
||||
try {
|
||||
const result1 = chunkCrew([], 0);
|
||||
const result2 = chunkCrew([], -5);
|
||||
const result3 = chunkCrew([1, 2, 3], 2);
|
||||
assert.isUndefined(result1);
|
||||
assert.isUndefined(result2);
|
||||
assert.lengthOf(spy.calls, 2);
|
||||
assert.match(spy.calls[0][0], /chunk\s*size\s*must\s*be\s*>=\s*1/i);
|
||||
assert.match(spy.calls[1][0], /chunk\s*size\s*must\s*be\s*>=\s*1/i);
|
||||
|
||||
} catch (err) {
|
||||
assert.fail(err);
|
||||
} finally {
|
||||
spy.restore();
|
||||
}
|
||||
```
|
||||
|
||||
After logging the error message, you should immediately call `return` to exit the function early.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeWhiteSpace(
|
||||
__helpers.removeJSComments(chunkCrew.toString())
|
||||
);
|
||||
const logReturnRegex = /console\.log\s*\([^)]*\)\s*;\s*return\b/g;
|
||||
const matches = cleaned.match(logReturnRegex) || [];
|
||||
const allLogs = cleaned.match(/console\.log\s*\([^)]*\)/g) || [];
|
||||
assert.strictEqual(
|
||||
matches.length,
|
||||
allLogs.length,
|
||||
"Every console.log(...) must be immediately followed by return"
|
||||
);
|
||||
|
||||
const spy = __helpers.spyOn(console, "log");
|
||||
try {
|
||||
const source = __helpers.removeJSComments(chunkCrew.toString());
|
||||
const instrumentedSource = source.replace(
|
||||
/\}\s*$/,
|
||||
'console.log("SENTINEL"); }'
|
||||
);
|
||||
const instrumentedFn = eval("(" + instrumentedSource + ")");
|
||||
instrumentedFn([], 0);
|
||||
assert.lengthOf(
|
||||
spy.calls,
|
||||
1,
|
||||
"Function must return immediately after logging validation error"
|
||||
);
|
||||
|
||||
assert.match(
|
||||
spy.calls[0][0],
|
||||
/chunk\s*size\s*must\s*be\s*>=\s*1/i
|
||||
);
|
||||
|
||||
} finally {
|
||||
spy.restore();
|
||||
}
|
||||
```
|
||||
|
||||
Your `chunkCrew` function should pass validation without errors when `size` is greater than or equal to 1.
|
||||
|
||||
```js
|
||||
const spy = __helpers.spyOn(console, "log");
|
||||
try {
|
||||
chunkCrew([], 1);
|
||||
chunkCrew([1, 2, 3], 2);
|
||||
|
||||
assert.lengthOf(
|
||||
spy.calls,
|
||||
0,
|
||||
"Valid size should not trigger console.log"
|
||||
);
|
||||
|
||||
} catch (err) {
|
||||
assert.fail(err);
|
||||
} finally {
|
||||
spy.restore();
|
||||
}
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
sortByPriorityDescending(eligible);
|
||||
|
||||
return eligible;
|
||||
}
|
||||
|
||||
const EVAReadySquad = getEVAReadyCrew(updatedSquad);
|
||||
|
||||
function chunkCrew(crew, size) {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,178 @@
|
||||
---
|
||||
id: 694f8510e8a0a3d89e146a01
|
||||
title: Step 24
|
||||
challengeType: 1
|
||||
dashedName: step-24
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To create chunks of size `n` from an `array` without changing it, you can combine a `for` loop with the `slice()` method as such:
|
||||
|
||||
```js
|
||||
const result = [];
|
||||
for (let i = 0; i < array.length; i += n) {
|
||||
result.push(array.slice(i, i + n));
|
||||
}
|
||||
```
|
||||
|
||||
The example above:
|
||||
|
||||
- creates an empty array named `result`
|
||||
|
||||
- loops through the original `array` in steps of size `n`
|
||||
|
||||
- creates chunks from `array` of size `n` and pushes them into `result` using `slice()`
|
||||
|
||||
To complete the `chunkCrew` function, you must:
|
||||
|
||||
- create an array named `chunks`
|
||||
|
||||
- loop through `crew` in steps of size `size`, creating and pushing chunks from `crew` into `chunks` using `slice()`
|
||||
|
||||
- return the `chunks` array
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create an empty array named `chunks`.
|
||||
|
||||
```js
|
||||
const funcStr = __helpers.removeJSComments(chunkCrew.toString());
|
||||
assert.match(
|
||||
funcStr,
|
||||
/(var|let|const)\s+chunks/,
|
||||
"You must have at least one space between the declaration keyword (let/const) and 'chunks'"
|
||||
);
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(chunkCrew.toString()));
|
||||
assert.match(cleaned, /(?:^|[^a-zA-Z])(var|let|const)chunks=\[\]/);
|
||||
```
|
||||
|
||||
You should use a `for` loop to build chunks.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(chunkCrew.toString()));
|
||||
assert.match(cleaned, /for\s*\(/);
|
||||
```
|
||||
|
||||
Inside the `for` loop, you should call `push()` on the `chunks` array to insert every sliced chunk (which must be created by calling `slice()` on the `crew` array).
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(chunkCrew.toString()));
|
||||
assert.match(cleaned, /chunks\.push\(crew\.slice\(/);
|
||||
```
|
||||
|
||||
After the loop, you should return the `chunks` array.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(chunkCrew.toString()));
|
||||
assert.match(cleaned, /returnchunks;?}$/);
|
||||
```
|
||||
|
||||
Your `chunkCrew` function should return chunks of length `size` from the input array `crew` without mutating it.
|
||||
|
||||
```js
|
||||
const sample = [1, 2, 3, 4, 5];
|
||||
const copyBefore = [...sample];
|
||||
const chunks = chunkCrew(sample, 2);
|
||||
assert.isArray(chunks);
|
||||
assert.deepEqual(chunks, [[1, 2], [3, 4], [5]]);
|
||||
assert.deepEqual(sample, copyBefore, 'chunkCrew should not mutate the original crew');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
sortByPriorityDescending(eligible);
|
||||
|
||||
return eligible;
|
||||
}
|
||||
|
||||
const EVAReadySquad = getEVAReadyCrew(updatedSquad);
|
||||
|
||||
function chunkCrew(crew, size) {
|
||||
if (size < 1) {
|
||||
console.log("Chunk size must be >= 1");
|
||||
return;
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
id: 69504214cbcb33319a1fa506
|
||||
title: Step 25
|
||||
challengeType: 1
|
||||
dashedName: step-25
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Use your `chunkCrew()` function to create chunks of size `3` from your `EVAReadySquad` array and store them in a new variable named `EVAChunks`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call `chunkCrew()` with `EVAReadySquad` and `3` and store the result in a new variable named `EVAChunks`.
|
||||
|
||||
```js
|
||||
assert.match(
|
||||
__helpers.removeJSComments(code),
|
||||
/(let|const)\s+EVAChunks/,
|
||||
"You must have at least one space between the declaration keyword (let/const) and 'EVAChunks'"
|
||||
);
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(code));
|
||||
assert.match(cleaned, /(let|const)EVAChunks=chunkCrew\(EVAReadySquad,?3\)/);
|
||||
assert.isArray(EVAChunks);
|
||||
assert.deepEqual(EVAChunks, [
|
||||
[
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
],
|
||||
[
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{id: 1, name: "Andy", role: "Commander", isEVAEligible: true, priority: 3},
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
],
|
||||
]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
sortByPriorityDescending(eligible);
|
||||
|
||||
return eligible;
|
||||
}
|
||||
|
||||
const EVAReadySquad = getEVAReadyCrew(updatedSquad);
|
||||
|
||||
function chunkCrew(crew, size) {
|
||||
if (size < 1) {
|
||||
console.log("Chunk size must be >= 1");
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks = [];
|
||||
for (let i = 0; i < crew.length; i += size) {
|
||||
chunks.push(crew.slice(i, i + size));
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,178 @@
|
||||
---
|
||||
id: 69504c249850e861921dca82
|
||||
title: Step 26
|
||||
challengeType: 1
|
||||
dashedName: step-26
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You may have noticed that `EVAChunks` is essentially an array with arrays inside of it, or a two-dimensional (2D) array. A nested `for` loop can be used to log data from a 2D array:
|
||||
|
||||
```js
|
||||
for (let i = 0; i < rootArray.length; i++) {
|
||||
console.log(`Group ${i + 1}:`);
|
||||
for (let j = 0; j < rootArray[i].length; j++) {
|
||||
console.log(rootArray[i][j].property);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In the example above, `rootArray` is the main array, `rootArray[i]` is a sub-array inside of the main array, and `rootArray[i][j]` is one object inside of that sub-array and `.property` accesses a value in that object.
|
||||
|
||||
Use a nested `for` loop to iterate through `EVAChunks` and log the `name` of every astronaut in each chunk. Be sure to:
|
||||
|
||||
- use `EVAChunks` as your root array
|
||||
- log `Chunk ${i+1}:` between chunks
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use a nested `for` loop to iterate through `EVAChunks` and log the `name` of every astronaut in each chunk. Log `Chunk ${i+1}:` between chunks.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(code));
|
||||
assert.match(
|
||||
cleaned,
|
||||
/for\([^)]*EVAChunks[^)]*\)\{[^}]*console\.log[^;]*Chunk\$\{[^}]+\}:/,
|
||||
'First for loop should iterate EVAChunks and log Chunk ${i+1}:'
|
||||
);
|
||||
assert.match(
|
||||
cleaned,
|
||||
/for\([^)]*EVAChunks[^)]*\)\{[\s\S]*?for\([^)]*EVAChunks[^)]*\)[\s\S]*?console\.log[^;]*EVAChunks\[[^\]]+\]\[[^\]]+\]\.name/,
|
||||
'Nested for loop should iterate inner EVAChunks elements using double indexing and log .name'
|
||||
);
|
||||
|
||||
function captureConsoleFromCode(code) {
|
||||
const logs = [];
|
||||
const originalLog = console.log;
|
||||
console.log = (...args) => logs.push(args.join(" "));
|
||||
try {
|
||||
const userScriptFn = new Function(code);
|
||||
userScriptFn();
|
||||
} finally {
|
||||
console.log = originalLog;
|
||||
}
|
||||
return logs;
|
||||
}
|
||||
const logs = captureConsoleFromCode(code)
|
||||
const expectedLogs = [
|
||||
"Chunk 1:", "Elise", "Felix", "Irene",
|
||||
"Chunk 2:", "Caroline", "Andy", "Hank"
|
||||
];
|
||||
assert.strictEqual(
|
||||
logs.length,
|
||||
expectedLogs.length,
|
||||
"You must log each chunk and each astronaut name exactly once"
|
||||
);
|
||||
assert.deepEqual(
|
||||
logs,
|
||||
expectedLogs,
|
||||
"Console output must log 'Chunk #' followed by the names of astronauts in each chunk in order"
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
sortByPriorityDescending(eligible);
|
||||
|
||||
return eligible;
|
||||
}
|
||||
|
||||
const EVAReadySquad = getEVAReadyCrew(updatedSquad);
|
||||
function chunkCrew(crew, size) {
|
||||
if (size < 1) {
|
||||
console.log("Chunk size must be >= 1");
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks = [];
|
||||
for (let i = 0; i < crew.length; i += size) {
|
||||
chunks.push(crew.slice(i, i + size));
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
const EVAChunks = chunkCrew(EVAReadySquad, 3);
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
id: 6951cfd4955dbb84cb9b8b22
|
||||
title: Step 8
|
||||
challengeType: 1
|
||||
dashedName: step-8
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You had previously added a `console.log()` call to your `addCrewMember` function to validate its behavior, and now the call is no longer needed. To prevent the terminal from getting cluttered in future steps, go ahead and remove the current `console.log()` call.
|
||||
|
||||
# --hints--
|
||||
|
||||
Remove the `console.log()` call from your `addCrewMember` function. You should delete the entire line.
|
||||
|
||||
```js
|
||||
const solution = (`constsquad=[];constfirstAstronaut={id:1,name:"Andy",role:"Commander",isEVAEligible:true,priority:3};functionaddCrewMember(crew,astronaut){for(leti=0;i<crew.length;i++){if(crew[i].id===astronaut.id){console.log("DuplicateID:"+astronaut.id);return;}}crew.push(astronaut);}addCrewMember(squad,firstAstronaut);constremainingCrew=[{id:2,name:"Bart",role:"Pilot",isEVAEligible:false,priority:8},{id:3,name:"Caroline",role:"Engineer",isEVAEligible:true,priority:4},{id:4,name:"Diego",role:"Scientist",isEVAEligible:false,priority:1},{id:5,name:"Elise",role:"Medic",isEVAEligible:true,priority:7},{id:6,name:"Felix",role:"Navigator",isEVAEligible:true,priority:6},{id:7,name:"Gertrude",role:"Communications",isEVAEligible:false,priority:4},{id:8,name:"Hank",role:"Mechanic",isEVAEligible:true,priority:2},{id:9,name:"Irene",role:"Specialist",isEVAEligible:true,priority:5},{id:10,name:"Joan",role:"Technician",isEVAEligible:false,priority:1},];for(leti=0;i<remainingCrew.length;i++){addCrewMember(squad,remainingCrew[i]);}`);
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(code));
|
||||
assert.strictEqual(cleaned, solution);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
--fcc-editable-region--
|
||||
console.log(`Added ${astronaut.name} as ${astronaut.role}`);
|
||||
--fcc-editable-region--
|
||||
}
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,88 @@
|
||||
---
|
||||
id: 6951d46955d890de029fdc30
|
||||
title: Step 15
|
||||
challengeType: 1
|
||||
dashedName: step-15
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You had previously added a `console.log()` call to your `swapCrewMembers` function to validate its behavior, and now the call is no longer needed. To prevent the terminal from getting cluttered in future steps, go ahead and remove the current `for` loop that logs to the console.
|
||||
|
||||
# --hints--
|
||||
|
||||
Remove the `for` loop from the `swapCrewMembers` function. You should delete the whole loop block.
|
||||
|
||||
```js
|
||||
const solution = (`constsquad=[];constfirstAstronaut={id:1,name:"Andy",role:"Commander",isEVAEligible:true,priority:3};functionaddCrewMember(crew,astronaut){for(leti=0;i<crew.length;i++){if(crew[i].id===astronaut.id){console.log("DuplicateID:"+astronaut.id);return;}}crew.push(astronaut);}addCrewMember(squad,firstAstronaut);constremainingCrew=[{id:2,name:"Bart",role:"Pilot",isEVAEligible:false,priority:8},{id:3,name:"Caroline",role:"Engineer",isEVAEligible:true,priority:4},{id:4,name:"Diego",role:"Scientist",isEVAEligible:false,priority:1},{id:5,name:"Elise",role:"Medic",isEVAEligible:true,priority:7},{id:6,name:"Felix",role:"Navigator",isEVAEligible:true,priority:6},{id:7,name:"Gertrude",role:"Communications",isEVAEligible:false,priority:4},{id:8,name:"Hank",role:"Mechanic",isEVAEligible:true,priority:2},{id:9,name:"Irene",role:"Specialist",isEVAEligible:true,priority:5},{id:10,name:"Joan",role:"Technician",isEVAEligible:false,priority:1},];for(leti=0;i<remainingCrew.length;i++){addCrewMember(squad,remainingCrew[i]);}functionswapCrewMembers(crew,fromIndex,toIndex){if(fromIndex<0||toIndex<0||fromIndex>=crew.length||toIndex>=crew.length){console.log("Invalidcrewindices");return;}constupdatedCrew=crew.slice();updatedCrew[fromIndex]=updatedCrew.splice(toIndex,1,updatedCrew[fromIndex])[0];returnupdatedCrew;}constupdatedSquad=swapCrewMembers(squad,2,5);`);
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(code));
|
||||
assert.strictEqual(cleaned, solution);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
--fcc-editable-region--
|
||||
for (let i = 0; i < updatedCrew.length; i++) {
|
||||
console.log(updatedCrew[i].name);
|
||||
}
|
||||
--fcc-editable-region--
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
```
|
||||
@@ -0,0 +1,112 @@
|
||||
---
|
||||
id: 6951d764550f436087782b6c
|
||||
title: Step 21
|
||||
challengeType: 1
|
||||
dashedName: step-21
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You added a `console.log()` call to your script to validate your `EVAReadySquad` array, and now the call is no longer needed. To prevent the terminal from getting cluttered in future steps, go ahead and remove the current `for` loop that logs `EVAReadySquad` astronauts to the console.
|
||||
|
||||
# --hints--
|
||||
|
||||
Remove the `for` loop that logs `EVAReadySquad` astronauts to the console. You should delete the whole loop block.
|
||||
|
||||
```js
|
||||
const solution = (`constsquad=[];constfirstAstronaut={id:1,name:"Andy",role:"Commander",isEVAEligible:true,priority:3};functionaddCrewMember(crew,astronaut){for(leti=0;i<crew.length;i++){if(crew[i].id===astronaut.id){console.log("DuplicateID:"+astronaut.id);return;}}crew.push(astronaut);}addCrewMember(squad,firstAstronaut);constremainingCrew=[{id:2,name:"Bart",role:"Pilot",isEVAEligible:false,priority:8},{id:3,name:"Caroline",role:"Engineer",isEVAEligible:true,priority:4},{id:4,name:"Diego",role:"Scientist",isEVAEligible:false,priority:1},{id:5,name:"Elise",role:"Medic",isEVAEligible:true,priority:7},{id:6,name:"Felix",role:"Navigator",isEVAEligible:true,priority:6},{id:7,name:"Gertrude",role:"Communications",isEVAEligible:false,priority:4},{id:8,name:"Hank",role:"Mechanic",isEVAEligible:true,priority:2},{id:9,name:"Irene",role:"Specialist",isEVAEligible:true,priority:5},{id:10,name:"Joan",role:"Technician",isEVAEligible:false,priority:1},];for(leti=0;i<remainingCrew.length;i++){addCrewMember(squad,remainingCrew[i]);}functionswapCrewMembers(crew,fromIndex,toIndex){if(fromIndex<0||toIndex<0||fromIndex>=crew.length||toIndex>=crew.length){console.log("Invalidcrewindices");return;}constupdatedCrew=crew.slice();updatedCrew[fromIndex]=updatedCrew.splice(toIndex,1,updatedCrew[fromIndex])[0];returnupdatedCrew;}constupdatedSquad=swapCrewMembers(squad,2,5);functionsortByPriorityDescending(crew){for(leti=0;i<crew.length-1;i++){for(letj=0;j<crew.length-1-i;j++){if(crew[j].priority<crew[j+1].priority){consttemp=crew[j];crew[j]=crew[j+1];crew[j+1]=temp;}}}}functiongetEVAReadyCrew(crew){consteligible=[];for(constastronautofcrew){if(astronaut.isEVAEligible)eligible.push(astronaut);}sortByPriorityDescending(eligible);returneligible;}constEVAReadySquad=getEVAReadyCrew(updatedSquad);`);
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(code));
|
||||
assert.strictEqual(cleaned, solution);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
sortByPriorityDescending(eligible);
|
||||
|
||||
return eligible;
|
||||
}
|
||||
|
||||
const EVAReadySquad = getEVAReadyCrew(updatedSquad);
|
||||
--fcc-editable-region--
|
||||
for (let i = 0; i < EVAReadySquad.length; i++) {
|
||||
console.log(EVAReadySquad[i].name);
|
||||
}
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,131 @@
|
||||
---
|
||||
id: 695a43cc94b29c92227efd46
|
||||
title: Step 27
|
||||
challengeType: 1
|
||||
dashedName: step-27
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You added a `console.log()` call to your script to validate your `EVAChunks` array, and now the call is no longer needed. To keep the terminal clean for the next steps, delete the `for loop` block that logs data from `EVAChunks`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove the `for loop` block that logs data from `EVAChunks`. Delete the whole block containing both loops.
|
||||
|
||||
```js
|
||||
const solution = (`constsquad=[];constfirstAstronaut={id:1,name:"Andy",role:"Commander",isEVAEligible:true,priority:3};functionaddCrewMember(crew,astronaut){for(leti=0;i<crew.length;i++){if(crew[i].id===astronaut.id){console.log("DuplicateID:"+astronaut.id);return;}}crew.push(astronaut);}addCrewMember(squad,firstAstronaut);constremainingCrew=[{id:2,name:"Bart",role:"Pilot",isEVAEligible:false,priority:8},{id:3,name:"Caroline",role:"Engineer",isEVAEligible:true,priority:4},{id:4,name:"Diego",role:"Scientist",isEVAEligible:false,priority:1},{id:5,name:"Elise",role:"Medic",isEVAEligible:true,priority:7},{id:6,name:"Felix",role:"Navigator",isEVAEligible:true,priority:6},{id:7,name:"Gertrude",role:"Communications",isEVAEligible:false,priority:4},{id:8,name:"Hank",role:"Mechanic",isEVAEligible:true,priority:2},{id:9,name:"Irene",role:"Specialist",isEVAEligible:true,priority:5},{id:10,name:"Joan",role:"Technician",isEVAEligible:false,priority:1},];for(leti=0;i<remainingCrew.length;i++){addCrewMember(squad,remainingCrew[i]);}functionswapCrewMembers(crew,fromIndex,toIndex){if(fromIndex<0||toIndex<0||fromIndex>=crew.length||toIndex>=crew.length){console.log("Invalidcrewindices");return;}constupdatedCrew=crew.slice();updatedCrew[fromIndex]=updatedCrew.splice(toIndex,1,updatedCrew[fromIndex])[0];returnupdatedCrew;}constupdatedSquad=swapCrewMembers(squad,2,5);functionsortByPriorityDescending(crew){for(leti=0;i<crew.length-1;i++){for(letj=0;j<crew.length-1-i;j++){if(crew[j].priority<crew[j+1].priority){consttemp=crew[j];crew[j]=crew[j+1];crew[j+1]=temp;}}}}functiongetEVAReadyCrew(crew){consteligible=[];for(constastronautofcrew){if(astronaut.isEVAEligible)eligible.push(astronaut);}sortByPriorityDescending(eligible);returneligible;}constEVAReadySquad=getEVAReadyCrew(updatedSquad);functionchunkCrew(crew,size){if(size<1){console.log("Chunksizemustbe>=1");return;}constchunks=[];for(leti=0;i<crew.length;i+=size){chunks.push(crew.slice(i,i+size));}returnchunks;}constEVAChunks=chunkCrew(EVAReadySquad,3);`);
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(code));
|
||||
assert.strictEqual(cleaned, solution);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
sortByPriorityDescending(eligible);
|
||||
|
||||
return eligible;
|
||||
}
|
||||
|
||||
const EVAReadySquad = getEVAReadyCrew(updatedSquad);
|
||||
function chunkCrew(crew, size) {
|
||||
if (size < 1) {
|
||||
console.log("Chunk size must be >= 1");
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks = [];
|
||||
for (let i = 0; i < crew.length; i += size) {
|
||||
chunks.push(crew.slice(i, i + size));
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
const EVAChunks = chunkCrew(EVAReadySquad, 3);
|
||||
|
||||
--fcc-editable-region--
|
||||
for (let i = 0; i < EVAChunks.length; i++) {
|
||||
console.log(`Chunk ${i + 1}:`);
|
||||
for (let j = 0; j < EVAChunks[i].length; j++) {
|
||||
console.log(EVAChunks[i][j].name);
|
||||
}
|
||||
}
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,131 @@
|
||||
---
|
||||
id: 695a4676b22517fd225b2497
|
||||
title: Step 28
|
||||
challengeType: 1
|
||||
dashedName: step-28
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Mission Control requires one more function for logging a summary of your crew. Create an empty function named `printCrewSummary` that accepts a `crew` parameter.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create a function named `printCrewSummary`.
|
||||
|
||||
```js
|
||||
assert.isFunction(printCrewSummary);
|
||||
```
|
||||
|
||||
Your `printCrewSummary` function should have a `crew` parameter.
|
||||
|
||||
```js
|
||||
const regex = __helpers.functionRegex('printCrewSummary', ['crew']);
|
||||
assert.match(__helpers.removeJSComments(printCrewSummary.toString()), regex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
sortByPriorityDescending(eligible);
|
||||
|
||||
return eligible;
|
||||
}
|
||||
|
||||
const EVAReadySquad = getEVAReadyCrew(updatedSquad);
|
||||
function chunkCrew(crew, size) {
|
||||
if (size < 1) {
|
||||
console.log("Chunk size must be >= 1");
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks = [];
|
||||
for (let i = 0; i < crew.length; i += size) {
|
||||
chunks.push(crew.slice(i, i + size));
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
const EVAChunks = chunkCrew(EVAReadySquad, 3);
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,134 @@
|
||||
---
|
||||
id: 695a4886b85613bdcd8dfc3f
|
||||
title: Step 29
|
||||
challengeType: 1
|
||||
dashedName: step-29
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
First, create a shallow copy of the input `crew` array using `slice()` and assign it to a variable named `sorted`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use the `slice()` method to copy the input `crew` array into a new variable named `sorted`.
|
||||
|
||||
```js
|
||||
const funcStr = __helpers.removeJSComments(printCrewSummary.toString());
|
||||
assert.match(
|
||||
funcStr,
|
||||
/(var|let|const)\s+sorted/,
|
||||
"You must have at least one space between the declaration keyword (let/const) and 'sorted'"
|
||||
);
|
||||
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(printCrewSummary.toString()));
|
||||
assert.match(cleaned, /(?:var|let|const)sorted=crew\.slice\(\);?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
sortByPriorityDescending(eligible);
|
||||
|
||||
return eligible;
|
||||
}
|
||||
|
||||
const EVAReadySquad = getEVAReadyCrew(updatedSquad);
|
||||
function chunkCrew(crew, size) {
|
||||
if (size < 1) {
|
||||
console.log("Chunk size must be >= 1");
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks = [];
|
||||
for (let i = 0; i < crew.length; i += size) {
|
||||
chunks.push(crew.slice(i, i + size));
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
const EVAChunks = chunkCrew(EVAReadySquad, 3);
|
||||
|
||||
function printCrewSummary(crew) {
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,132 @@
|
||||
---
|
||||
id: 695a4a70d5843b7f18c1050f
|
||||
title: Step 30
|
||||
challengeType: 1
|
||||
dashedName: step-30
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Directly sort the local `sorted` array by using your helper function `sortByPriorityDescending()`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should invoke `sortByPriorityDescending()` with the `sorted` array.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(printCrewSummary.toString()));
|
||||
assert.match(cleaned, /(?:^|[^a-zA-Z])sortByPriorityDescending\(sorted\)/);
|
||||
const viableSolutions = [`functionprintCrewSummary(crew){constsorted=crew.slice();sortByPriorityDescending(sorted);}`, `functionprintCrewSummary(crew){constsorted=crew.slice();sortByPriorityDescending(sorted)}`, `functionprintCrewSummary(crew){varsorted=crew.slice();sortByPriorityDescending(sorted);}`, `functionprintCrewSummary(crew){varsorted=crew.slice();sortByPriorityDescending(sorted)}`];
|
||||
assert.ok(
|
||||
viableSolutions.includes(cleaned)
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
sortByPriorityDescending(eligible);
|
||||
|
||||
return eligible;
|
||||
}
|
||||
|
||||
const EVAReadySquad = getEVAReadyCrew(updatedSquad);
|
||||
function chunkCrew(crew, size) {
|
||||
if (size < 1) {
|
||||
console.log("Chunk size must be >= 1");
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks = [];
|
||||
for (let i = 0; i < crew.length; i += size) {
|
||||
chunks.push(crew.slice(i, i + size));
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
const EVAChunks = chunkCrew(EVAReadySquad, 3);
|
||||
|
||||
function printCrewSummary(crew) {
|
||||
const sorted = crew.slice();
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,175 @@
|
||||
---
|
||||
id: 695a4b4afad548377ea2f146
|
||||
title: Step 31
|
||||
challengeType: 1
|
||||
dashedName: step-31
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Use a `for` loop to log the `name` of every astronaut in the `sorted` array.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use a `for` loop to iterate through the `sorted` array and log the `name` of each astronaut.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(printCrewSummary.toString()))
|
||||
assert.match(cleaned, /for\s*\(/);
|
||||
function captureConsole(fn) {
|
||||
const logs = [];
|
||||
const originalLog = console.log;
|
||||
console.log = (...args) => logs.push(args.join(" "));
|
||||
try {
|
||||
fn();
|
||||
} finally {
|
||||
console.log = originalLog;
|
||||
}
|
||||
return logs;
|
||||
}
|
||||
const testCrew = [
|
||||
{ name: "Andy", priority: 3 },
|
||||
{ name: "Bart", priority: 8 },
|
||||
{ name: "Caroline", priority: 4 },
|
||||
{ name: "Diego", priority: 1 },
|
||||
{ name: "Elise", priority: 7 },
|
||||
{ name: "Felix", priority: 6 },
|
||||
{ name: "Gertrude", priority: 4 },
|
||||
{ name: "Hank", priority: 2 },
|
||||
{ name: "Irene", priority: 5 },
|
||||
{ name: "Joan", priority: 1 }
|
||||
];
|
||||
const logs = captureConsole(() => printCrewSummary(testCrew));
|
||||
const expectedOrder = [
|
||||
"Bart",
|
||||
"Elise",
|
||||
"Felix",
|
||||
"Irene",
|
||||
"Caroline",
|
||||
"Gertrude",
|
||||
"Andy",
|
||||
"Hank",
|
||||
"Diego",
|
||||
"Joan"
|
||||
];
|
||||
assert.strictEqual(
|
||||
logs.length,
|
||||
expectedOrder.length,
|
||||
"You must log each astronaut's name exactly once"
|
||||
);
|
||||
assert.deepEqual(
|
||||
logs,
|
||||
expectedOrder,
|
||||
"Names must be logged in descending priority order"
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
sortByPriorityDescending(eligible);
|
||||
|
||||
return eligible;
|
||||
}
|
||||
|
||||
const EVAReadySquad = getEVAReadyCrew(updatedSquad);
|
||||
function chunkCrew(crew, size) {
|
||||
if (size < 1) {
|
||||
console.log("Chunk size must be >= 1");
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks = [];
|
||||
for (let i = 0; i < crew.length; i += size) {
|
||||
chunks.push(crew.slice(i, i + size));
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
const EVAChunks = chunkCrew(EVAReadySquad, 3);
|
||||
|
||||
function printCrewSummary(crew) {
|
||||
const sorted = crew.slice();
|
||||
sortByPriorityDescending(sorted);
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,263 @@
|
||||
---
|
||||
id: 695a4c4742aa88ce805940ac
|
||||
title: Step 32
|
||||
challengeType: 1
|
||||
dashedName: step-32
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To complete preparation for your space mission, call `printCrewSummary()` with your `updatedSquad` array!
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call your `printCrewSummary()` function with `updatedSquad`.
|
||||
|
||||
```js
|
||||
const cleaned = __helpers.removeWhiteSpace(__helpers.removeJSComments(code));
|
||||
assert.match(cleaned, /printCrewSummary\(updatedSquad\)/, "Call printCrewSummary with updatedSquad");
|
||||
|
||||
function captureConsoleFromCode(code) {
|
||||
const logs = [];
|
||||
const originalLog = console.log;
|
||||
console.log = (...args) => logs.push(args.join(" "));
|
||||
try {
|
||||
const userScriptFn = new Function(code);
|
||||
userScriptFn();
|
||||
} finally {
|
||||
console.log = originalLog;
|
||||
}
|
||||
return logs;
|
||||
}
|
||||
const logs = captureConsoleFromCode(code);
|
||||
const expectedNames = ["Bart", "Elise", "Felix", "Irene", "Caroline", "Gertrude", "Andy", "Hank", "Diego", "Joan"];
|
||||
assert.deepEqual(
|
||||
logs,
|
||||
expectedNames,
|
||||
"console.log must match the result of calling printCrewSummary(updatedSquad)"
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
sortByPriorityDescending(eligible);
|
||||
|
||||
return eligible;
|
||||
}
|
||||
|
||||
const EVAReadySquad = getEVAReadyCrew(updatedSquad);
|
||||
function chunkCrew(crew, size) {
|
||||
if (size < 1) {
|
||||
console.log("Chunk size must be >= 1");
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks = [];
|
||||
for (let i = 0; i < crew.length; i += size) {
|
||||
chunks.push(crew.slice(i, i + size));
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
const EVAChunks = chunkCrew(EVAReadySquad, 3);
|
||||
|
||||
function printCrewSummary(crew) {
|
||||
const sorted = crew.slice();
|
||||
sortByPriorityDescending(sorted);
|
||||
for (const astronaut of sorted) {
|
||||
console.log(astronaut.name);
|
||||
}
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const squad = [];
|
||||
|
||||
const firstAstronaut = {
|
||||
id: 1,
|
||||
name: "Andy",
|
||||
role: "Commander",
|
||||
isEVAEligible: true,
|
||||
priority: 3
|
||||
};
|
||||
|
||||
function addCrewMember(crew, astronaut) {
|
||||
for (let i = 0; i < crew.length; i++) {
|
||||
if (crew[i].id === astronaut.id) {
|
||||
console.log("Duplicate ID: " + astronaut.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
crew.push(astronaut);
|
||||
}
|
||||
|
||||
addCrewMember(squad, firstAstronaut);
|
||||
|
||||
const remainingCrew = [
|
||||
{ id: 2, name: "Bart", role: "Pilot", isEVAEligible: false, priority: 8 },
|
||||
{ id: 3, name: "Caroline", role: "Engineer", isEVAEligible: true, priority: 4 },
|
||||
{ id: 4, name: "Diego", role: "Scientist", isEVAEligible: false, priority: 1 },
|
||||
{ id: 5, name: "Elise", role: "Medic", isEVAEligible: true, priority: 7 },
|
||||
{ id: 6, name: "Felix", role: "Navigator", isEVAEligible: true, priority: 6 },
|
||||
{ id: 7, name: "Gertrude", role: "Communications", isEVAEligible: false, priority: 4 },
|
||||
{ id: 8, name: "Hank", role: "Mechanic", isEVAEligible: true, priority: 2 },
|
||||
{ id: 9, name: "Irene", role: "Specialist", isEVAEligible: true, priority: 5 },
|
||||
{ id: 10, name: "Joan", role: "Technician", isEVAEligible: false, priority: 1 },
|
||||
];
|
||||
|
||||
for (let i = 0; i < remainingCrew.length; i++) {
|
||||
addCrewMember(squad, remainingCrew[i]);
|
||||
}
|
||||
|
||||
function swapCrewMembers(crew, fromIndex, toIndex) {
|
||||
if (
|
||||
fromIndex < 0 ||
|
||||
toIndex < 0 ||
|
||||
fromIndex >= crew.length ||
|
||||
toIndex >= crew.length
|
||||
) {
|
||||
console.log("Invalid crew indices");
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCrew = crew.slice();
|
||||
updatedCrew[fromIndex] = updatedCrew.splice(toIndex, 1, updatedCrew[fromIndex])[0];
|
||||
|
||||
return updatedCrew;
|
||||
}
|
||||
|
||||
const updatedSquad = swapCrewMembers(squad, 2, 5);
|
||||
|
||||
function sortByPriorityDescending(crew) {
|
||||
for (let i = 0; i < crew.length - 1; i++) {
|
||||
for (let j = 0; j < crew.length - 1 - i; j++) {
|
||||
if (crew[j].priority < crew[j + 1].priority) {
|
||||
const temp = crew[j];
|
||||
crew[j] = crew[j + 1];
|
||||
crew[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEVAReadyCrew(crew) {
|
||||
const eligible = [];
|
||||
for (const astronaut of crew) {
|
||||
if (astronaut.isEVAEligible) eligible.push(astronaut);
|
||||
}
|
||||
sortByPriorityDescending(eligible);
|
||||
|
||||
return eligible;
|
||||
}
|
||||
|
||||
const EVAReadySquad = getEVAReadyCrew(updatedSquad);
|
||||
function chunkCrew(crew, size) {
|
||||
if (size < 1) {
|
||||
console.log("Chunk size must be >= 1");
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks = [];
|
||||
for (let i = 0; i < crew.length; i += size) {
|
||||
chunks.push(crew.slice(i, i + size));
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
const EVAChunks = chunkCrew(EVAReadySquad, 3);
|
||||
|
||||
function printCrewSummary(crew) {
|
||||
const sorted = crew.slice();
|
||||
sortByPriorityDescending(sorted);
|
||||
for (const astronaut of sorted) {
|
||||
console.log(astronaut.name);
|
||||
}
|
||||
}
|
||||
|
||||
printCrewSummary(updatedSquad);
|
||||
```
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "Build a Space Mission Roster",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "workshop-space-mission-roster",
|
||||
"helpCategory": "JavaScript",
|
||||
"blockLayout": "challenge-grid",
|
||||
"challengeOrder": [
|
||||
{ "id": "694c40d86fe6a78d20b6559c", "title": "Step 1" },
|
||||
{ "id": "694c84106e9023f289c03b84", "title": "Step 2" },
|
||||
{ "id": "694c84330cbe604821b9deef", "title": "Step 3" },
|
||||
{ "id": "694c9c186c089f7bdff0f3c6", "title": "Step 4" },
|
||||
{ "id": "694ca14c8ef00056ad146e51", "title": "Step 5" },
|
||||
{ "id": "694cabb9f1afa9446f36ffc0", "title": "Step 6" },
|
||||
{ "id": "694cada4bc0242600b5f21ea", "title": "Step 7" },
|
||||
{ "id": "6951cfd4955dbb84cb9b8b22", "title": "Step 8" },
|
||||
{ "id": "694ce8609fb805ba21cebc02", "title": "Step 9" },
|
||||
{ "id": "694d8c16f3672c498d4656ac", "title": "Step 10" },
|
||||
{ "id": "694d8ddbfc4bb6940b921bbc", "title": "Step 11" },
|
||||
{ "id": "694d8ddd106340237efb0c80", "title": "Step 12" },
|
||||
{ "id": "694d98a87c2a7a33ca92cfa9", "title": "Step 13" },
|
||||
{ "id": "694dfd604c32cfe8e298784c", "title": "Step 14" },
|
||||
{ "id": "6951d46955d890de029fdc30", "title": "Step 15" },
|
||||
{ "id": "694e0952a3742f2898aef517", "title": "Step 16" },
|
||||
{ "id": "694e0c6e2cf8b9b45755f0f5", "title": "Step 17" },
|
||||
{ "id": "694e1931f6509ae16aa1c36f", "title": "Step 18" },
|
||||
{ "id": "694eeb57faae3b2331add3e7", "title": "Step 19" },
|
||||
{ "id": "694eef2a7aa196d5f4fa96b9", "title": "Step 20" },
|
||||
{ "id": "6951d764550f436087782b6c", "title": "Step 21" },
|
||||
{ "id": "694f55431c34fe3ab17c482f", "title": "Step 22" },
|
||||
{ "id": "694f7cae8b5aa1f91cb33c8b", "title": "Step 23" },
|
||||
{ "id": "694f8510e8a0a3d89e146a01", "title": "Step 24" },
|
||||
{ "id": "69504214cbcb33319a1fa506", "title": "Step 25" },
|
||||
{ "id": "69504c249850e861921dca82", "title": "Step 26" },
|
||||
{ "id": "695a43cc94b29c92227efd46", "title": "Step 27" },
|
||||
{ "id": "695a4676b22517fd225b2497", "title": "Step 28" },
|
||||
{ "id": "695a4886b85613bdcd8dfc3f", "title": "Step 29" },
|
||||
{ "id": "695a4a70d5843b7f18c1050f", "title": "Step 30" },
|
||||
{ "id": "695a4b4afad548377ea2f146", "title": "Step 31" },
|
||||
{ "id": "695a4c4742aa88ce805940ac", "title": "Step 32" }
|
||||
],
|
||||
"blockLabel": "workshop",
|
||||
"usesMultifileEditor": true,
|
||||
"hasEditableBoundaries": true
|
||||
}
|
||||
@@ -96,6 +96,7 @@
|
||||
"blocks": [
|
||||
"lecture-working-with-loops",
|
||||
"workshop-sentence-analyzer",
|
||||
"workshop-space-mission-roster",
|
||||
"lab-longest-word-in-a-string",
|
||||
"lab-factorial-calculator",
|
||||
"lab-mutations",
|
||||
|
||||
Reference in New Issue
Block a user