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:
Luis
2026-03-14 05:28:45 -07:00
committed by GitHub
parent f61cd9fbf8
commit 81685bcbbb
35 changed files with 3899 additions and 0 deletions

View File

@@ -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": [

View File

@@ -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--
```

View File

@@ -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--
```

View File

@@ -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--
```

View File

@@ -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--
}
```

View File

@@ -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--
}
```

View File

@@ -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--
```

View File

@@ -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--
```

View File

@@ -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--
```

View File

@@ -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--
}
```

View File

@@ -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--
}
```

View File

@@ -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--
}
```

View File

@@ -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--
}
```

View File

@@ -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--
```

View File

@@ -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--
```

View File

@@ -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--
}
```

View File

@@ -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 theyre 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;
}
```

View File

@@ -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;
}
```

View File

@@ -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--
```

View File

@@ -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--
```

View File

@@ -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--
}
```

View File

@@ -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--
}
```

View File

@@ -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--
```

View File

@@ -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--
```

View File

@@ -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]);
}
```

View File

@@ -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);
```

View File

@@ -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--
```

View File

@@ -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--
```

View File

@@ -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--
```

View File

@@ -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--
}
```

View File

@@ -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--
}
```

View File

@@ -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--
}
```

View File

@@ -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);
```

View File

@@ -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
}

View File

@@ -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",