add translation of algorithm and data structures (#40678)

This commit is contained in:
Xing Liu
2021-01-12 08:18:51 -08:00
committed by GitHub
parent a469138ae4
commit 306e4aaacf
62 changed files with 757 additions and 641 deletions

View File

@ -1,13 +1,13 @@
---
id: 5a661e0f1068aca922b3ef17
title: 使用方括号访问数组的内容
title: 使用方括号访问数组的元素
challengeType: 1
forumTopicId: 301149
---
# --description--
所有数据结构的基本特性是,它们不仅能够存储数据,我们还能够按照需求来访问存放在其中的数据。我们已经学习了如何创建一个数组结构,现在让我们开始学习如何访问这个数组结构中的数据。
所有数据结构的基本特性是,它们不仅可以存储数据,还可以让我们按需访问存放在其中的数据。我们已经学习了如何创建数组,现在让我们学习如何访问数组中的数据。
我们先定义一个包含 3 个元素的数组:
@ -15,47 +15,47 @@ forumTopicId: 301149
let ourArray = ["a", "b", "c"];
```
一个数组结构中,内部的每个元素都有一个与之对应的<dfn>索引</dfn><dfn>index</dfn>)。索引是该元素在数组中的位置,可被用于引用该元素。但需要注意的是JavaScript 数组的索引是从0开始的(<dfn>zero-indexed</dfn>),即一个数组的第一个元素是在数组中的***第 0 个***位置,而不是第 1 个位置。 要从一个数组中获取一个元素,我们可以在一个数组变量名的后面加一个使用“方括号”括起来的索引。这叫做<dfn>方括号符号</dfn><dfn>bracket notation</dfn>)。如我们要从`ourArray`数组变量中获取数据元素`"a"`并将其赋值给一个变量,我们可以编写如下所示的代码
数组中,内部的每个元素都有一个与之对应的<dfn>索引</dfn><dfn>index</dfn>)。索引是该元素在数组中的位置,也是我们访问该元素的参考。需要注意的是JavaScript 数组的索引是从 0 开始的(这种从 0 开始的规则叫做 <dfn>zero-indexed</dfn>),即数组的第一个元素是在数组中的***第 0 个***位置,而不是第 1 个位置。要从数组中获取一个元素,我们可以在数组字面量后面加一个用方括号(`[]`)括起来的索引。不过习惯上,我们会通过表示数组的变量名来访问,而不是直接通过字面量。这种从数组中读取元素的方式叫做<dfn>方括号表示法</dfn><dfn>bracket notation</dfn>)。如我们要从数组 `ourArray` 中获取数据元素 `"a"` 并将其赋值给一个变量,可以这样写
```js
let ourVariable = ourArray[0];
// ourVariable 的值为 "a"
```
除了使用 “索引” 来获取某个元素值以外,你还可以通过类似的法来*设置*一个索引位置所对应的元素值:
除了使用索引来获取某个元素值以外,你还可以通过类似的法来*设置*一个索引位置的元素值:
```js
ourArray[1] = "not b anymore";
// ourArray 现在的值为 ["a", "not b anymore", "c"];
```
我们现在已经利用方括号将索引为 1 的元素从`"b"`设置为了`"not b anymore"`
在上面的代码中,我们用方括号表示法把索引为 1 的元素从 `"b"` 改成了 `"not b anymore"`
# --instructions--
在本挑战中,请`myArray`第二个元素(索引`1`)设置为除了`"b"`以外的任意值。
在本挑战中,请将 `myArray` 中的第二个元素(索引`1`)设置为除了 `"b"` 以外的任意值。
# --hints--
`myArray[0]`等于`"a"`
`myArray[0]` 应为 `"a"`
```js
assert.strictEqual(myArray[0], 'a');
```
`myArray[1]`不再设置为`"b"`
`myArray[1]` 不应为 `"b"`
```js
assert.notStrictEqual(myArray[1], 'b');
```
`myArray[2]`等于`"c"`
`myArray[2]` 应为 `"c"`
```js
assert.strictEqual(myArray[2], 'c');
```
`myArray[3]`等于`"d"`
`myArray[3]` 应为 `"d"`
```js
assert.strictEqual(myArray[3], 'd');

View File

@ -7,28 +7,28 @@ forumTopicId: 301150
# --description--
在关于对象的第一个挑战中,我们提到可以在方括号符号中用一个变量作为属性名来访问属性值。假设一个超市收银台程序中使用了一个`foods`对象,并且有一些程序逻辑会设置`selectedFood`我们需要查询`foods`对象来检查某种食物是否存在,我们可以这样写检查逻辑
在关于对象的第一个挑战中,我们提到可以在一对方括号中用一个变量作为属性名来访问属性值。假设一个超市收银台程序中一个 `foods` 对象,并且有一个函数会设置 `selectedFood`;如果我们需要查询 `foods` 对象中,某种食物是否存在,可以这样实现
```js
let selectedFood = getCurrentFood(scannedItem);
let inventory = foods[selectedFood];
```
上述代码会先计算`selectedFood`变量的值,并返回`foods`对象中以该值命名的属性对应的值,若没有以该值命名的属性则会返回`undefined`。有时候对象的属性名在运行之前是不确定的,或者我们需要动态地访问对象的属性,这时方括号符号就会很有用。
上述代码会先读取 `selectedFood` 变量的值,并返回 `foods` 对象中以该值命名的属性对应的属性值。若没有以该值命名的属性则会返回 `undefined`。有时候对象的属性名在运行之前是不确定的,或者我们需要动态地访问对象的属性值。在这些场景下,方括号表示法就变得十分有用。
# --instructions--
我们已经定义了一个`checkInventory`函数,它接受一个被扫描到的商品名作为输入参数。它要返回`foods`对象中`scannedItem`的值命名的属性的值。只有有效的属性名会作为参数传入`checkInventory`,你在完成挑战时不需处理参数无效的情况。
我们已经定义了 `checkInventory` 函数,它接受一个被扫描到的商品名作为输入参数。请让这个函数返回 `foods` 对象中,以 `scannedItem` 的值命名的属性对应的属性值。在本挑战中,只有合理有效的属性名会作为参数传入 `checkInventory`因此你不需处理参数无效的情况。
# --hints--
`checkInventory`是一个函数
`checkInventory`是一个函数
```js
assert.strictEqual(typeof checkInventory, 'function');
```
`foods`对象应该只有以下键值对: `apples: 25` `oranges: 32` `plums: 28` `bananas: 13` `grapes: 35` `strawberries: 27`
`foods` 对象应只包含以下键值对:`apples: 25``oranges: 32``plums: 28``bananas: 13``grapes: 35``strawberries: 27`
```js
assert.deepEqual(foods, {
@ -41,19 +41,19 @@ assert.deepEqual(foods, {
});
```
`checkInventory("apples")`返回`25`
`checkInventory("apples")` 应返回 `25`
```js
assert.strictEqual(checkInventory('apples'), 25);
```
`checkInventory("bananas")`返回`13`
`checkInventory("bananas")` 应返回 `13`
```js
assert.strictEqual(checkInventory('bananas'), 13);
```
`checkInventory("strawberries")`返回`27`
`checkInventory("strawberries")` 应返回 `27`
```js
assert.strictEqual(checkInventory('strawberries'), 27);

View File

@ -1,15 +1,15 @@
---
id: 587d78b2367417b2b2512b0e
title: 使用 push() 和 unshift() 添加项目到数组中
title: 使用 push() 和 unshift() 为数组添加元素
challengeType: 1
forumTopicId: 301151
---
# --description--
一个数组的长度与包含的数据类型一样,是不固定的。数组可以包含任意数量的元素,可以不限次数地往数组中添加元素或者从中移除元素,或者说数组是<dfn>可变的</dfn><dfn>mutable</dfn>)。在本挑战中,我们要学习两个以编程方式修改数组的方法:`Array.push()``Array.unshift()`
数组的长度与数组能包含的数据类型一样,是不固定的。数组可以包含任意数量的元素,可以不限次数地往数组中添加元素或者从中移除元素。总之,数组是<dfn>可变的</dfn><dfn>mutable</dfn>)。在本挑战中,我们要学习两修改数组的方法:`Array.push()``Array.unshift()`
这两个方法都接收一个或多个元素作为参数;对一个数组调用这两个方法都可以将输入的元素插入到该数组中`push()`方法将元素插入到一个数组的末尾,而`unshift()`方法将元素插入到一个数组的开头。请看以下例子:
这两个方法都接收一个或多个元素作为参数,并会将参数中的元素添加到该数组中`push()` 方法将元素插入到数组的末尾,而 `unshift()` 方法将元素插入到数组的开头。请看以下例子:
```js
let twentyThree = 'XXIII';
@ -22,15 +22,15 @@ romanNumerals.push(twentyThree);
// 数组现在为 ['XIX', 'XX', 'XXI', 'XXII', 'XXIII']
```
注意,我们还可以入变量,这允许我们很灵活地动态改变我们数组中的数据
**注意:**我们甚至可以入变量,这在动态改变数组数据的场景下十分有用
# --instructions--
我们已经定义了一个`mixedNumbers`函数,它会接受一个数组作为参数。请你修改这个函数,使用`push()``unshift()`来将`'I', 2, 'three'`插入到数组开头,将`7, 'VIII', 9`插入到数组的末尾,使得这个函数返回一个依次包含 1-9 的数组
我们已经定义了一个 `mixedNumbers` 函数,它接收一个数组作为参数。请你修改这个函数,使用 `push()``unshift()` 来将 `'I', 2, 'three'` 插入到数组开头,将 `7, 'VIII', 9` 插入到数组的末尾,使得这个函数返回一个依次包含 1 至 9
# --hints--
`mixedNumbers(["IV", 5, "six"])`现在应该返回`["I", 2, "three", "IV", 5, "six", 7, "VIII", 9]`
`mixedNumbers(["IV", 5, "six"])`返回 `["I", 2, "three", "IV", 5, "six", 7, "VIII", 9]`
```js
assert.deepEqual(mixedNumbers(['IV', 5, 'six']), [
@ -46,13 +46,13 @@ assert.deepEqual(mixedNumbers(['IV', 5, 'six']), [
]);
```
`mixedNumbers`函数应该使用`push()`方法
`mixedNumbers` 函数中应调用 `push()` 方法
```js
assert(mixedNumbers.toString().match(/\.push/));
```
`mixedNumbers`函数应该使用`unshift()`方法
`mixedNumbers` 函数中应调用 `unshift()` 方法
```js
assert(mixedNumbers.toString().match(/\.unshift/));

View File

@ -1,13 +1,13 @@
---
id: 587d78b3367417b2b2512b11
title: 使用 splice() 增加项目
title: 使用 splice() 添加元素
challengeType: 1
forumTopicId: 301152
---
# --description--
还记得在上个挑战中我们提到`splice()`方法可以接受最多 3 个参数吗?我们现在可以进一步了解`splice()`除了移除元素,我们还可以利用它的第三个参数来向数组中*添加*元素。第三个参数可以是一个或多个元素,这些元素会被添加到数组中。这使我们能够便捷地将数组中的一个或一系列元素换成其他的元素。例如:
还记得在上个挑战中我们提到 `splice()` 方法最多可以接 3 个参数吗?除了移除元素,我们还可以利用它的第三个参数来向数组中*添加*元素。第三个参数可以是一个或多个元素,这些元素会被添加到数组中。这样,我们能够便捷地将数组中的一个或多个连续元素换成其他的元素。例如:
```js
const numbers = [10, 11, 12, 12, 15];
@ -20,15 +20,15 @@ console.log(numbers);
// 返回 [ 10, 11, 12, 13, 14, 15 ]
```
以一个数字数组开始。接着调用 `splice()` 方法, (3) 的索引位置开始删除元素,删除的元素数量是 (1)(13, 14) 是在删除位置插入的元素,可以在 `amountToDelete` 后面入任意数量的元素(以逗号分隔),每个都会被插入。
在上面的代码中,数组开始包含了若干数字。接着,我们调用 `splice()` 方法,索引为 (3) 的地方开始删除元素,删除的元素数量是 (1)。然后(13, 14) 是在删除位置插入的元素,可以在 `amountToDelete` 后面入任意数量的元素(以逗号分隔),每个都会被插入到数组中
# --instructions--
我们已经定义了一个`htmlColorNames`函数,它以一个 HTML 颜色的数组作为输入参数。请修改这个函数,利用`splice()`来移除数组中的前两个元素,并在对应的位置上添加`'DarkSalmon'``'BlanchedAlmond'`
我们已经定义了一个 `htmlColorNames` 函数,它以一个 HTML 颜色的数组作为输入参数。请修改这个函数,使用 `splice()` 来移除数组中的前两个元素,并在对应的位置上添加 `'DarkSalmon'``'BlanchedAlmond'`
# --hints--
`htmlColorNames`返回`["DarkSalmon", "BlanchedAlmond", "LavenderBlush", "PaleTurqoise", "FireBrick"]`
`htmlColorNames` 应返回 `["DarkSalmon", "BlanchedAlmond", "LavenderBlush", "PaleTurqoise", "FireBrick"]`
```js
assert.deepEqual(
@ -49,19 +49,19 @@ assert.deepEqual(
);
```
`htmlColorNames`函数应该使用`splice()`方法
`htmlColorNames` 函数中应调用 `splice()` 方法
```js
assert(/.splice/.test(code));
```
不应使用`shift()``unshift()`
不应使用 `shift()``unshift()`
```js
assert(!/shift|unshift/.test(code));
```
不应使用数组括号表示法。
不应使用数组的方括号表示法。
```js
assert(!/\[\d\]\s*=/.test(code));

View File

@ -7,64 +7,80 @@ forumTopicId: 301153
# --description--
对象object本质上是<dfn>键值对key-value pair</dfn>的集合或者说,一系列被映射到唯一标识符叫做<dfn>属性property</dfn>或者<dfn>key</dfn>数据。让我们来看一个简单的例子:
对象object本质上是<dfn>键值对key-value pair</dfn>的集合或者说,一系列被映射到唯一标识符的数据就是对象;习惯上,唯一标识符叫做<dfn>属性property</dfn>或者<dfn>key</dfn>数据叫做<dfn>value</dfn>。让我们来看一个简单的例子:
```js
let FCC_User = {
username: 'awesome_coder',
followers: 572,
points: 1741,
completedProjects: 15
const tekkenCharacter = {
player: 'Hwoarang',
fightingStyle: 'Tae Kwon Doe',
human: true
};
```
上面的代码定义了一个叫做`FCC_User`对象它有 4 个<dfn>属性</dfn>,每个属性映射一个特定的值。如果我们想知道`FCC_User`有多少`followers`,我们可以这样访问其`followers`属性
上面的代码定义了一个叫做 `tekkenCharacter` 的“铁拳”游戏人物对象它有三个属性,每个属性都对应一个特定的值。如果我们想为它再添加一个叫做 `origin` 的属性,可以这样写
```js
let userData = FCC_User.followers;
// userData 等于 572
tekkenCharacter.origin = 'South Korea';
```
这叫做<dfn>dot notation</dfn>我们还可以用方括号符号来访问对象中的属性
上面的代码中,我们使用了<dfn>点号表示法dot notation</dfn>如果我们现在输出这个对象,便可以看到它具有 `origin` 属性。接下来,因为这个人物在游戏中有着与众不同的橘色头发,我们可以通过方括号表示法来为它添加这个属性,像这样
```js
let userData = FCC_User['followers'];
// userData 等于 572
tekkenCharacter['hair color'] = 'dyed orange';
```
注意,在用<dfn>方括号符号</dfn>时,我们在括号里写的是字符串`followers`(用引号括起)。方括号符号让我们能用一个变量作为属性名来访问对象的属性(请记住)。若我们在方括号中不写引号而直接写`followers`JavaScript 引擎会将其看作一个变量,并抛出一个`ReferenceError: followers is not defined`的错误。
如果要设置的属性中存在空格,或者要设置的属性是一个变量,那我们必须使用<dfn>方括号表示法bracket notation</dfn>来为对象添加属性。在上面的代码中,我们把属性 `hair color` 放到引号里,以此来表示整个字符串都是需要设置的属性。如果我们不加上引号,那么中括号里的内容会被当作一个变量来解析,这个变量对应的值就会作为要设置的属性,请看这段代码:
```js
const eyes = 'eye color';
tekkenCharacter[eyes] = 'brown';
```
执行以上所有示例代码后,对象会变成这样:
```js
{
player: 'Hwoarang',
fightingStyle: 'Tae Kwon Doe',
human: true,
origin: 'South Korea',
'hair color': 'dyed orange',
'eye color': 'brown'
};
```
# --instructions--
用这样的语法,我们还可以向对象中***新增***键值对。我们已经创建了一个有 3 个属性的`foods`对象,请为其新增 3 项:值为`13``bananas`属性值为`35``grapes`属性值为`27``strawberries`属性。
我们已经为你创建了 `foods` 对象。请使用上述任意语法,来为 `foods` 对象添加如下三个键值对:`bananas` 属性值为 `13``grapes` 属性值为 `35``strawberries` 属性,值为 `27`
# --hints--
`foods`应该是一个对象。
`foods` 应为一个对象。
```js
assert(typeof foods === 'object');
```
`foods`有一个值为`13``"bananas"`属性。
`foods` 应有一个值为 `13``"bananas"` 属性。
```js
assert(foods.bananas === 13);
```
`foods`有一个值为`35``"grapes"`属性。
`foods` 应有一个值为 `35``"grapes"` 属性。
```js
assert(foods.grapes === 35);
```
`foods`有一个值为`27``"strawberries"`属性。
`foods` 应有一个值为 `27``"strawberries"` 属性。
```js
assert(foods.strawberries === 27);
```
你应该用点符号或者方括号符号来设置对象的属性。
应使用点号表示法或方括号表示法来设置对象的属性。
```js
assert(

View File

@ -7,7 +7,7 @@ forumTopicId: 301154
# --description--
由于数组可以在任意时间被修改或者说*被改变(mutated*,我们不能保证某个数据在一个给定数组中的位置,甚至不能保证该元素还存在于该数组中。幸运的JavaScript 我们提供了另一个内置方法`indexOf()`。这个方法让我们可以便地检查某个元素是否存在于一个数组中。`indexOf()`方法接受一个元素作为输入参数,并返回该元素在数组中的位置(索引);若该元素不存在于数组中则返回`-1`
由于数组随时都可以修改或发生“突变”(*mutated*),我们很难保证某个数据始终处于数组中的特定位置,甚至不能保证该元素是否还存在于该数组中。好消息JavaScript 我们提供了内置方法 `indexOf()`。这个方法让我们可以便地检查某个元素是否存在于数组中。`indexOf()` 方法接受一个元素作为输入参数,并返回该元素在数组中的位置(索引);若该元素不存在于数组中则返回 `-1`
例如:
@ -16,16 +16,16 @@ let fruits = ['apples', 'pears', 'oranges', 'peaches', 'pears'];
fruits.indexOf('dates'); // 返回 -1
fruits.indexOf('oranges'); // 返回 2
fruits.indexOf('pears'); // 返回 1第一个出现的 'pears' 元素在数组中的索引为 1
fruits.indexOf('pears'); // 返回 1因为第一个出现在数组中的 'pears' 元素索引为 1
```
# --instructions--
`indexOf()`在快速检查一个数组中是否存在某个元素时非常有用。我们已经定义了一个`quickCheck`函数,它接受一个数组和一个元素作为输入参数。请修改这个函数,利用`indexOf()`方法,使得当输入的数组中含有输入的元素时,函数返回`true`;不含有输入的元素时,函数返回`false`
`indexOf()` 在快速检查一个数组中是否存在某个元素时非常有用。我们已经定义了一个 `quickCheck` 函数,它接受一个数组和一个元素作为输入参数。请修改这个函数,通过 `indexOf()` 方法,使得当参数数组中包含第二个参数的元素时返回 `true`,不包含时返回 `false`
# --hints--
`quickCheck(["squash", "onions", "shallots"], "mushrooms")`返回`false`
`quickCheck(["squash", "onions", "shallots"], "mushrooms")` 应返回 `false`
```js
assert.strictEqual(
@ -34,7 +34,7 @@ assert.strictEqual(
);
```
`quickCheck(["squash", "onions", "shallots"], "onions")`返回`true`
`quickCheck(["squash", "onions", "shallots"], "onions")` 应返回 `true`
```js
assert.strictEqual(
@ -43,19 +43,19 @@ assert.strictEqual(
);
```
`quickCheck([3, 5, 9, 125, 45, 2], 125)`返回`true`
`quickCheck([3, 5, 9, 125, 45, 2], 125)` 应返回 `true`
```js
assert.strictEqual(quickCheck([3, 5, 9, 125, 45, 2], 125), true);
```
`quickCheck([true, false, false], undefined)`应返回`false`
`quickCheck([true, false, false], undefined)` 应返回 `false`
```js
assert.strictEqual(quickCheck([true, false, false], undefined), false);
```
`quickCheck`函数应使用`indexOf()`方法
`quickCheck` 函数应使用 `indexOf()` 方法
```js
assert.notStrictEqual(quickCheck.toString().search(/\.indexOf\(/), -1);

View File

@ -7,7 +7,7 @@ forumTopicId: 301155
# --description--
现在我们可以新增、修改和移除对象中的属性。但如果我们想知道一个对象中是否含某个属性呢JavaScript 为我们提供了两种不同的方式来实现这个功能一个是`hasOwnProperty()`方法,另一个是`in`关键字。如我们有一个`users`对象,它有一个`Alan`属性,我们可以用以下两种方式之一来检查该属性在对象中是否存在
我们已经学习了如果添加、修改和移除对象中的属性。但如果我们想知道一个对象中是否含某个属性呢JavaScript 为我们提供了两种不同的方式来实现这个功能一个是通过 `hasOwnProperty()` 方法,另一个是使用 `in` 关键字。如我们有一个 `users` 对象,为检查它是否含有 `Alan` 属性,可以这样写
```js
users.hasOwnProperty('Alan');
@ -17,11 +17,11 @@ users.hasOwnProperty('Alan');
# --instructions--
我们已经创建了一个含有一些用户的`users`对象和一个`isEveryoneHere`函数,该函数接`users`对象作为参数。请完成该函数使其在`users`对象中包含以下 4 个键`Alan``Jeff``Sarah``Ryan`时才返回`true`,否则返回`false`
我们已经定义了一个包含若干用户信息的 `users` 对象和一个 `isEveryoneHere` 函数,该函数接`users` 对象作为参数。请完成该函数使其在 `users` 对象中同时包含 `Alan``Jeff``Sarah``Ryan` 四个属性时才返回 `true`,否则返回 `false`
# --hints--
`users`对象应该只含有`Alan``Jeff``Sarah``Ryan`4 个
`users` 对象应该只包含 `Alan``Jeff``Sarah``Ryan` 4 个属性
```js
assert(
@ -33,13 +33,13 @@ assert(
);
```
`isEveryoneHere`函数在`users`对象包含`Alan``Jeff``Sarah``Ryan`4 个时应返回`true`
`isEveryoneHere` 函数在 `users` 对象包含 `Alan``Jeff``Sarah``Ryan` 4 个属性时应返回 `true`
```js
assert(isEveryoneHere(users) === true);
```
`isEveryoneHere`函数在`users`对象不包含`Alan``Jeff``Sarah``Ryan`4 个时应返回`false`
`isEveryoneHere` 函数在 `users` 对象不包含 `Alan``Jeff``Sarah``Ryan` 4 个属性时应返回 `false`
```js
assert(
@ -50,7 +50,7 @@ assert(
);
```
如果 `Jeff` 不是 `users` 对象的属性,函数 `isEveryoneHere`返回 `false`
如果 `users` 对象中不包含属性 `Jeff`,则函数 `isEveryoneHere` 应返回 `false`
```js
assert(
@ -61,7 +61,7 @@ assert(
);
```
如果 `Sarah` 不是 `users` 对象的属性,函数 `isEveryoneHere`返回 `false`
如果 `users` 对象中不包含属性 `Sarah`,则函数 `isEveryoneHere` 应返回 `false`
```js
assert(
@ -72,7 +72,7 @@ assert(
);
```
如果 `Ryan` 不是 `users` 对象的属性,函数 `isEveryoneHere`返回 `false`
如果 `users` 对象中不包含属性 `Ryan`,则函数 `isEveryoneHere` 应返回 `false`
```js
assert(

View File

@ -1,13 +1,13 @@
---
id: 587d7b7b367417b2b2512b17
title: 组合使用数组和扩展运算符
title: 使用展开运算符合并数组
challengeType: 1
forumTopicId: 301156
---
# --description--
<dfn>展开运算符</dfn>的另一个大用处是合并数组,或者将某个数组的所有元素插入到另一个数组的任意位置。用传统的语法我们也可以连接两个数组,但只能两个数组首尾相接。而展开语法能使下面的操作变得极其简单:
<dfn>展开语法</dfn>的另一个重要用途是合并数组,或者将某个数组的所有元素插入到另一个数组的任意位置。我们也可以使用 ES5 的语法连接两个数组,但只能让它们首尾相接。而展开语法可以让这样的操作变得极其简单:
```js
let thisArray = ['sage', 'rosemary', 'parsley', 'thyme'];
@ -16,21 +16,21 @@ let thatArray = ['basil', 'cilantro', ...thisArray, 'coriander'];
// thatArray 现在是 ['basil', 'cilantro', 'sage', 'rosemary', 'parsley', 'thyme', 'coriander']
```
使用展开语法,我们这样就实现一个用传统方法写得很复杂冗长的操作。
使用展开语法,我们这样就可以实现一个用传统方法写得很复杂冗长的操作。
# --instructions--
我们已经定义了一个返回`sentence`变量的`spreadOut`函数请修改函数,利用<dfn>展开运算符</dfn>使该函数返回数组`['learning', 'to', 'code', 'is', 'fun']`
我们已经定义了一个返回 `sentence` 变量的 `spreadOut` 函数请修改这个函数,利用<dfn>展开语法</dfn>使该函数返回数组 `['learning', 'to', 'code', 'is', 'fun']`
# --hints--
`spreadOut`返回`["learning", "to", "code", "is", "fun"]`
`spreadOut` 应返回 `["learning", "to", "code", "is", "fun"]`
```js
assert.deepEqual(spreadOut(), ['learning', 'to', 'code', 'is', 'fun']);
```
`spreadOut`函数里应用到展开语法
`spreadOut` 函数里应用到展开语法
```js
assert.notStrictEqual(spreadOut.toString().search(/[...]/), -1);

View File

@ -1,30 +1,30 @@
---
id: 587d7b7b367417b2b2512b13
title: 使用展运算符复制数组
title: 使用展运算符复制数组
challengeType: 1
forumTopicId: 301157
---
# --description--
`slice()`已经能让我们从一个数组中选择一些元素来复制到新数组中,而 ES6 中又引入了一个简洁且可读性强的语法<dfn>展开运算符spread operator</dfn>,它能让我们方便地复制数组中的*所有*元素。展开语法是这样`...`
`slice()` 可以让我们从一个数组中选择一些元素来复制到新数组中,而 ES6 中又引入了一个简洁且可读性强的语法<dfn>展开运算符spread operator</dfn>,它能让我们方便地复制数组中的*所有*元素。展开语法写出来是这样:`...`
在实践中,我们可以这样用展开运算符来复制一个数组:
我们可以用展开运算符来复制数组:
```js
let thisArray = [true, true, undefined, false, null];
let thatArray = [...thisArray];
// thatArray 等于 [true, true, undefined, false, null]
// thisArray 保持不变,等于 thatArray
// thatArray 的值现在也是 [true, true, undefined, false, null]
// thisArray 保持不变。现在 thatArray 所包含的值与 thisArray 完全相同
```
# --instructions--
我们已经定义了一个`copyMachine`函数,它接受`arr`(一个数组)和`num`(一个数字)作为输入参数。该函数应该返回一个由`num``arr`组成的新数组。我们已经为你写好了大部分的代码,但它还不能正确地工作。请修改这个函数,使用展开语法,使该函数正确工作(提示:我们已经学到过的一个方法很适合用在这里
我们已经定义了一个 `copyMachine` 函数,它接受 `arr`(一个数组)和 `num`(一个数字)作为输入参数。该函数需要返回一个由 `num``arr` 组成的新的二维数组。同时,我们写好了大致的流程,只是细节实现还没有写完。请修改这个函数,使用展开语法,使该函数能正常工作(提示:我们已经学到过的一个方法很适合用在这里)
# --hints--
`copyMachine([true, false, true], 2)`返回`[[true, false, true], [true, false, true]]`
`copyMachine([true, false, true], 2)` 应返回 `[[true, false, true], [true, false, true]]`
```js
assert.deepEqual(copyMachine([true, false, true], 2), [
@ -33,7 +33,7 @@ assert.deepEqual(copyMachine([true, false, true], 2), [
]);
```
`copyMachine([1, 2, 3], 5)`返回`[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]`
`copyMachine([1, 2, 3], 5)` 应返回 `[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]`
```js
assert.deepEqual(copyMachine([1, 2, 3], 5), [
@ -45,13 +45,13 @@ assert.deepEqual(copyMachine([1, 2, 3], 5), [
]);
```
`copyMachine([true, true, null], 1)`返回`[[true, true, null]]`
`copyMachine([true, true, null], 1)` 应返回 `[[true, true, null]]`
```js
assert.deepEqual(copyMachine([true, true, null], 1), [[true, true, null]]);
```
`copyMachine(["it works"], 3)`返回`[["it works"], ["it works"], ["it works"]]`
`copyMachine(["it works"], 3)` 应返回 `[["it works"], ["it works"], ["it works"]]`
```js
assert.deepEqual(copyMachine(['it works'], 3), [
@ -61,7 +61,7 @@ assert.deepEqual(copyMachine(['it works'], 3), [
]);
```
`copyMachine`函数中应该对数组`arr`使用`spread operator`
`copyMachine` 函数中应`arr` 使用`展开运算符`
```js
assert(removeJSComments(code).match(/\.\.\.arr/));

View File

@ -1,13 +1,13 @@
---
id: 587d7b7a367417b2b2512b12
title: 使用 slice() 拷贝数组项目
title: 使用 slice() 复制数组元素
challengeType: 1
forumTopicId: 301158
---
# --description--
接下来我们要介绍`slice()`方法。`slice()`并不修改数组,而是复制或者说*提取extract*给定数量的元素到一个新数组里,而调用方法的数组保持不变。`slice()`只接 2 个输入参数第一个是开始提取元素的位置(索引),第二个是结束提取元素的位置索引。slice 方法会提取直到截止索引的元素,但被提取的元素不包括截止索引对应的元素。请看以下例子:
接下来我们要介绍 `slice()` 方法。`slice()` 不会修改数组,而是复制或者说*提取extract*给定数量的元素到一个新数组。同时,调用方法的数组保持不变。`slice()` 只接 2 个输入参数第一个是开始提取元素的位置(索引),第二个是提取元素的结束位置(索引)。`slice()` 提取的元素中不包括第二个参数所对应的元素。请看以下例子:
```js
let weatherConditions = ['rain', 'snow', 'sleet', 'hail', 'clear'];
@ -17,15 +17,15 @@ let todaysWeather = weatherConditions.slice(1, 3);
// weatherConditions 仍然等于 ['rain', 'snow', 'sleet', 'hail', 'clear']
```
在我们从一个已有的数组中提取了一些元素,并用这些元素创建了一个新数组。
上面的代码中,我们从一个数组中提取了一些元素,并用这些元素创建了一个新数组。
# --instructions--
我们已经定义了一个`forecast`函数,它接受一个数组作为参数。请修改这个函数,利用`slice()`从输入的数组中提取信息,返回一个包含元素`'warm'``'sunny'` 的新数组。
我们已经定义了一个 `forecast` 函数,它接受一个数组作为参数。请修改这个函数,利用 `slice()` 从输入的数组中提取信息,最终返回一个包含元素 `'warm'``'sunny'` 的新数组。
# --hints--
`forecast`返回`["warm", "sunny"]`
`forecast` 应返回 `["warm", "sunny"]`
```js
assert.deepEqual(
@ -34,7 +34,7 @@ assert.deepEqual(
);
```
`forecast`函数应使用`slice()`方法
`forecast` 函数应使用 `slice()` 方法
```js
assert(/\.slice\(/.test(code));

View File

@ -7,37 +7,37 @@ forumTopicId: 301159
# --description--
很好!你已经学到很多关于数组的知识了但这些只是个开始,你将在接下来的小节中学习到与数组相关的更多知识。在继续学习<dfn>对象</dfn><dfn>Objects</dfn>)之前,让我们再花一点时间看一看,数组怎样能够变得比之前的挑战中更复杂一点
很好!你现在已经学到很多关于数组的知识了但这些只是个开始。我们将在接下来的中挑战中学到更多与数组相关的知识。在继续学习<dfn>对象</dfn><dfn>Objects</dfn>)之前,让我们再花一点时间了解下更复杂的数组嵌套
数组的一个强大的特性是,它可以包含其他数组,甚至完全由其他数组组成。我们已经在上一个挑战中到了包含数组的数组,但它还算是比较简单的。数组中的数组还可以包含其他数组,数组中是可以嵌套任意层的数组的。数组从而可以被用来实现非常复杂的叫做<dfn>多维multi-dimensional</dfn>或嵌套nested数组的数据结构。请看如下例
数组的一个强大的特性是,它可以包含其他数组,甚至完全由其他数组组成。在上一个挑战中,我们已经接触到了包含数组的数组,但它还算是比较简单的。数组中的数组还可以包含其他数组,可以嵌套任意多层数组。习惯上,我们称这种数据结构为<dfn>多维multi-dimensional数组</dfn>或嵌套nested数组。请看如下的示例:
```js
let nestedArray = [ // 顶层,或第 1 层——最外层数组
let nestedArray = [ // 顶层,或第 1 层,即最外层数组
['deep'], // 数组中的数组,第 2 层
[
['deeper'], ['deeper'] // 第 3 层嵌套的两个数组
['deeper'], ['deeper'] // 第 3 层,元素为嵌套的两个数组
],
[
[
['deepest'], ['deepest'] // 第 4 层嵌套的两个数组
['deepest'], ['deepest'] // 第 4 层,元素为嵌套的两个数组
],
[
[
['deepest-est?'] // 第 5 层嵌套的一个数组
['deepest-est?'] // 第 5 层,元素为嵌套的一个数组
]
]
]
];
```
虽然这个例子看起来错综复杂,但这样复杂的数组并不算罕见,尤其是在处理大量数据的时候。 但我们仍能简单地用方括号符号来访问嵌套得最深的数组:
虽然这个例子看起来错综复杂,不过,尤其是在处理大量数据的时候,这种数据结构还是经常会用到的。尽管结构复杂,不过我们仍可以通过方括号表示法来访问嵌套得最深的数组:
```js
console.log(nestedArray[2][1][0][0][0]);
// logs: deepest-est?
```
既然我们知道数据在哪里,我们就能修改它:
既然我们知道数据的位置,当然,我们也可以修改它:
```js
nestedArray[2][1][0][0][0] = 'deeper still';
@ -48,11 +48,11 @@ console.log(nestedArray[2][1][0][0][0]);
# --instructions--
我们已经定义了一个`myNestedArray`数组变量。请修改`myNestedArray`,用<dfn>字符串string</dfn><dfn>数字number</dfn><dfn>布尔值boolean</dfn>作为数组的数据元素,使得`myNestedArray`刚好有 5 层数组嵌套(记住,最外层的数组是第 1 层)。请在第 3 层的数组中包含字符串`'deep'`在第 4 层的数组中包含字符串`'deeper'`,在第 5 层的数组中包含字符串`'deepest'`
我们已经定义了一个叫做 `myNestedArray`数组变量。请修改 `myNestedArray`使<dfn>字符串string</dfn><dfn>数字number</dfn><dfn>布尔值boolean</dfn>作为数组的元素,并让 `myNestedArray` 刚好有 5 层(注意,最外层的数组是第 1 层)。同时,请在第 3 层的数组中包含字符串 `'deep'`在第 4 层的数组中包含字符串 `'deeper'`,在第 5 层的数组中包含字符串 `'deepest'`
# --hints--
`myNestedArray`中的数据元素应当只能是字符串、数字或者布尔值。
`myNestedArray` 中的数据元素应只包含字符串、数字或者布尔值。
```js
assert.strictEqual(
@ -76,7 +76,7 @@ assert.strictEqual(
);
```
`myNestedArray`应该刚好有 5 层数组嵌套
`myNestedArray` 应刚好包含 5 层嵌套数组
```js
assert.strictEqual(
@ -99,7 +99,7 @@ assert.strictEqual(
);
```
`myNestedArray`里应该有且只有一个字符串`"deep"`,并且应出现在第 3 层数组中。
`myNestedArray` 中应只有一个字符串 `"deep"`,并且应出现在第 3 层数组中。
```js
assert(
@ -128,7 +128,7 @@ assert(
);
```
`myNestedArray`里应该有且只有一个字符串`"deeper"`,并且应出现在第 4 层数组中。
`myNestedArray` 中应只有一个字符串 `"deeper"`,并且应出现在第 4 层数组中。
```js
assert(
@ -157,7 +157,7 @@ assert(
);
```
`myNestedArray`里应该有且只有一个字符串`"deepest"`,并且应出现在第 5 层数组中。
`myNestedArray` 中应只有一个字符串 `"deepest"`,并且应出现在第 5 层数组中。
```js
assert(

View File

@ -1,21 +1,21 @@
---
id: 587d7b7d367417b2b2512b1e
title: 使用 Object.Keys() 生成对象所有组成的数组
title: 使用 Object.keys() 生成对象所有属性组成的数组
challengeType: 1
forumTopicId: 301160
---
# --description--
我们可以输入一个对象作为参数来调用`Object.keys()`方法,使其生成一个包含对象中所有键的数组。这会返回一个由对象中所有键的名称(字符串)组成的数组。再次说明,这个数组中的项的顺序是不确定的。
我们可以`Object.keys()` 方法传入一个对象作为参数,这会返回一个由对象中所有属性(字符串)组成的数组。需要注意的是,数组中元素的顺序是不确定的。
# --instructions--
完成`getArrayOfUsers`函数,使其返回一个包含输入对象的所有属性的数组。
请完成 `getArrayOfUsers` 函数的实现,使其返回一个输入对象的所有属性所组成的数组。
# --hints--
`users`对象应该只包含`Alan``Jeff``Sarah``Ryan`这 4 个
`users` 对象应该只包含 `Alan``Jeff``Sarah``Ryan` 这 4 个属性。
```js
assert(
@ -27,7 +27,7 @@ assert(
);
```
`getArrayOfUsers`函数应返回一个包含`users`对象中所有的数组
`getArrayOfUsers` 函数应返回一个包含 `users` 对象中所有属性的数组
```js
assert(

View File

@ -1,15 +1,15 @@
---
id: 587d7b7b367417b2b2512b15
title: 使用 For 循环迭代数组的所有项
title: 使用 for 循环遍历数组中的全部元素
challengeType: 1
forumTopicId: 301161
---
# --description--
在进行与数组有关的编程时,我们有时需要遍历数组的所有元素来找出我们需要的元素,或者对数组执行特定的操作。JavaScript 提供了几个内置的方法,它们以不同的方式遍历数组来获得不同的结果(如`every()``forEach()``map()`等等)。简单的`for`循环不仅能实现这些功能,而且相比之下也灵活。
使用数组时,我们经常需要遍历数组的所有元素来找出我们需要的一个或多个元素,抑或是对数组执行一些特定的操作。JavaScript 为我们提供了几个内置的方法,它们以不同的方式遍历数组,以便我们可以用于不同的场景(如 `every()``forEach()``map()` 等等)。然而,最简单的 `for` 循环不仅能实现上述这些方法的功能,而且相比之下也会更加灵活。
请看以下例子:
请看以下例子:
```js
function greaterThanTen(arr) {
@ -26,15 +26,15 @@ greaterThanTen([2, 12, 8, 14, 80, 0, 1]);
// 返回 [12, 14, 80]
```
这个函数使用一个`for`循环来遍历一个数组,逐一对其中的元素进行测试。我们用这个方法简单地以编程的方式找出数组中大于`10`元素,并返回一个包含这些元素的数组。
这个函数中,我们用一个 `for` 循环来遍历数组,逐一对其中的元素进行判断。通过上面的代码,我们可以找出数组中大于 `10` 的所有元素,并返回一个包含这些元素的数组。
# --instructions--
我们已经定义了一个`filteredArray`函数,它接受一个嵌套的数组参数`arr`以及一个`elem`参数,并要返回一个新数组。`arr`数组中的数组可能包含`elem`元素,也可能不包含。请修改该函数,用一个`for`循环来做筛选,使函数返回一个由`arr`中不包含`elem`的数组组成的新数组。
我们已经定义了 `filteredArray` 函数,它接受一个嵌套的数组 `arr`一个 `elem` 作为参数,并要返回一个新数组。`arr` 数组中嵌套的数组可能包含 `elem` 元素,也可能不包含。请修改该函数,用一个 `for` 循环来做筛选,使函数返回一个由 `arr` 中不包含 `elem` 的数组组成的新数组。
# --hints--
`filteredArray([[10, 8, 3], [14, 6, 23], [3, 18, 6]], 18)`返回`[ [10, 8, 3], [14, 6, 23] ]`
`filteredArray([[10, 8, 3], [14, 6, 23], [3, 18, 6]], 18)` 应返回 `[ [10, 8, 3], [14, 6, 23] ]`
```js
assert.deepEqual(
@ -53,7 +53,7 @@ assert.deepEqual(
);
```
`filteredArray([ ["trumpets", 2], ["flutes", 4], ["saxophones", 2] ], 2)`应返回`[ ["flutes", 4] ]`
`filteredArray([ ["trumpets", 2], ["flutes", 4], ["saxophones", 2] ], 2)` 应返回 `[ ["flutes", 4] ]`
```js
assert.deepEqual(
@ -69,7 +69,7 @@ assert.deepEqual(
);
```
`filteredArray([ ["amy", "beth", "sam"], ["dave", "sean", "peter"] ], "peter")`返回`[ ["amy", "beth", "sam"] ]`
`filteredArray([ ["amy", "beth", "sam"], ["dave", "sean", "peter"] ], "peter")` 应返回 `[ ["amy", "beth", "sam"] ]`
```js
assert.deepEqual(
@ -84,7 +84,7 @@ assert.deepEqual(
);
```
`filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3)`返回`[ ]`
`filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3)` 应返回 `[]`
```js
assert.deepEqual(
@ -101,7 +101,7 @@ assert.deepEqual(
);
```
`filteredArray`函数应使用`for`循环
`filteredArray` 函数应使用 `for` 循环
```js
assert.notStrictEqual(filteredArray.toString().search(/for/), -1);

View File

@ -1,32 +1,31 @@
---
id: 587d7b7d367417b2b2512b1d
title: 使用 for...in 语句迭代对象
title: 使用 for...in 语句遍历对象
challengeType: 1
forumTopicId: 301162
---
# --description--
有时候你需要遍历一个对象中的所有键。这需要 JavaScript 中的一个特殊语法:<dfn>for...in</dfn> 语句。以遍历 `users` 对象的为例:
如果我们想要遍历对象中的所有属性,只需要使用 JavaScript 中的 <dfn>for...in</dfn> 语句即可。以遍历 `users` 对象的属性为例:
```js
for (let user in users) {
console.log(user);
}
// logs:
// 输出:
Alan
Jeff
Sarah
Ryan
```
这个语句中,我们定义了一个`user`变量,你可以看到,这个变量在 for...in 语句对对象的每一个键的遍历中都会被重置。 **注意:**
跟数组不同,对象中的键是无序的,因此一个对象中某个键的位置,或者说它出现的相对顺序,在引用或访问该键时是不确定的。
上面的代码中,我们定义了一个 `user` 变量。可以观察到,这个变量在遍历对象的 `for...in` 语句执行过程中会一直被重置并赋予新值,结果就是不同的用户名打印到了 console 中。**注意:**对象中的键是无序的,这与数组不同。因此,一个对象中某个属性的位置,或者说它出现的相对顺序,在引用或访问该属性时是不确定的。
# --instructions--
我们已经定义了一个`countOnline`函数,请在其中使用一个 <dfn>for...in</dfn> 语句来遍历`users`对象中的用户,并返回`online`属性为`true`的用户数量。
我们已经定义了一个 `countOnline` 函数,请在其中使用 <dfn>for...in</dfn> 语句来遍历 `users` 对象中的用户,并返回 `online` 属性为 `true` 的用户数量。以下是一个传入 `countOnline` 函数的对象示例,注意每个用户都有 `online` 属性,其属性值为 `true``false`
```js
{
@ -44,7 +43,7 @@ Ryan
# --hints--
函数 `countOnline`使用 `for in` 语句遍历传入对象的key
函数 `countOnline` 应使用 `for in` 语句遍历传入对象。
```js
assert(
@ -54,19 +53,19 @@ assert(
);
```
当传入 `{ Alan: { online: false }, Jeff: { online: true }, Sarah: { online: false } }` 时,函数 `countOnline` 应该返回 `1`
当传入 `{ Alan: { online: false }, Jeff: { online: true }, Sarah: { online: false } }` 时,函数 `countOnline` 应该返回 `1`
```js
assert(countOnline(usersObj1) === 1);
```
当传入 `{ Alan: { online: true }, Jeff: { online: false }, Sarah: { online: true } }` 时,函数 `countOnline` 应该返回 `2`
当传入 `{ Alan: { online: true }, Jeff: { online: false }, Sarah: { online: true } }` 时,函数 `countOnline` 应该返回 `2`
```js
assert(countOnline(usersObj2) === 2);
```
当传入 `{ Alan: { online: false }, Jeff: { online: false }, Sarah: { online: false } }` 时,函数 `countOnline` 应该返回 `0`
当传入 `{ Alan: { online: false }, Jeff: { online: false }, Sarah: { online: false } }` 时,函数 `countOnline` 应该返回 `0`
```js
assert(countOnline(usersObj3) === 0);

View File

@ -7,21 +7,21 @@ forumTopicId: 301163
# --description--
现在你已经接触到 JavaScript 对象的所有运算。你可以增加、修改移除键值对检查某个是否存在,并且遍历一个对象的所有。在继续学习 JavaScript 的过程中,你会看到对象的更多用法。另外,后续的《高级数据结构课程还会介绍 ES6 的 <dfn>Map</dfn><dfn>Set</dfn> 对象。这两种对象都跟一般的对象相似,但它们提供了一些额外的特性。现在你已经学了数组和对象的基础知识,你已经可以继续用 JavaScript 来解决更加复杂的问题了!
我们已经学习了 JavaScript 对象的这些基本操作:添加、修改移除键值对检查某个属性是否存在、遍历对象的所有属性。在继续学习 JavaScript 的过程中,我们会了解对象的更多用法。另外,在之后的数据结构课程中,我们还会学习 ES6 的 <dfn>Map</dfn><dfn>Set</dfn>。这两种数据结构与我们现在学到的对象十分类似,但它们在对象的基础上提供了一些额外的功能。目前,我们已经学了数组和对象的基础知识,让我们试着来用所学的知识解决一些更复杂的问题
# --instructions--
看一下代码编辑器中我们提供的对象。`user`对象包含 3 个键。`data`对象包含 5 个,其中一个包含一个`friends`数组。从这个例子你可以看到对象作为数据结构是多么的灵活。我们已经写`addFriend`函数的一部分,请你完成这个函数,使其接受一个`user`对象,将`friend`参数中的名字添加到`user.data.friends`数组中并返回该数组。
请看一下代码编辑器中我们为你写好的对象。`user` 对象包含 3 个属性;`data` 对象包含 5 个属性,其中包含一个叫做 `friends`数组。这就是对象作为数据结构所展现出的灵活。我们已经写好了 `addFriend` 函数的一部分,请你完成这个函数,使其接受一个 `user` 对象,将 `friend` 参数中的名字添加到 `user.data.friends` 数组中并返回该数组。
# --hints--
`user`对象应该包含`name``age``data`三个
`user` 对象应该包含 `name``age``data` 三个属性
```js
assert('name' in user && 'age' in user && 'data' in user);
```
`addFriend`函数应该接受一个`user`对象和一个`friend`字符串作为输入参数,并将 friend 插入到`user`对象的`friends`数组中。
`addFriend` 函数应该接受一个 `user` 对象和一个 `friend` 字符串作为输入参数,并将这个字符串插入到 `user` 对象的 `friends` 数组中。
```js
assert(
@ -34,7 +34,7 @@ assert(
);
```
`addFriend(user, "Pete")`应该返回`["Sam", "Kira", "Tomo", "Pete"]`
`addFriend(user, "Pete")` 应该返回 `["Sam", "Kira", "Tomo", "Pete"]`
```js
assert.deepEqual(

View File

@ -7,7 +7,7 @@ forumTopicId: 301164
# --description--
现在我们来看一个稍复杂一点的对象。对象中也可以嵌套任意层的对象对象的属性值可以是 JavaScript 支持的任意类型,包括数组和其他对象。请看以下例子:
现在我们来看一个稍复杂的对象。对象中,我们也可以嵌套任意层的对象对象的属性值可以是 JavaScript 支持的任意类型,包括数组和其他对象。请看以下例子:
```js
let nestedObject = {
@ -24,15 +24,19 @@ let nestedObject = {
};
```
`nestedObject`有 3 个唯一的键:值为一个数字的`id`、值为一个字符串`date`和值为一个嵌套了其他对象的对象的`data`。虽然对象中的数据可能很复杂,我们仍能使用上一个挑战中讲的符号来访问我们需要的信息。
`nestedObject` 有 3 个属性:`id`(属性值为数字)、`date`(属性值为字符串)、`data`(属性值为嵌套的对象)。虽然对象中的数据可能很复杂,我们仍能使用上一个挑战中讲到的写法来访问我们需要的信息。如果我们想把嵌套在 `onlineStatus``busy` 的属性值改为 `10`,可以用点号表示法来这样实现:
```js
nestedObject.data.onlineStatus.busy = 10;
```
# --instructions--
我们已经定义了一个`userActivity`对象,它包含了另一个对象。你可以用上一个挑战中那样的方式来修改被嵌套的对象的属性。请将`online`属性设为`45`
我们已经定义了一个 `userActivity` 对象,它包含了另一个对象。请将 `online` 的属性值改为 `45`
# --hints--
`userActivity`应该含有`id``date``data`属性。
`userActivity` 应包含 `id``date``data` 属性。
```js
assert(
@ -40,19 +44,19 @@ assert(
);
```
`userActivity`应该有一个`data`属性,属性要是一个含有`totalUsers``online`属性的对象。
`userActivity` 应包含 `data` 属性,属性值应为包含 `totalUsers``online` 属性的对象。
```js
assert('totalUsers' in userActivity.data && 'online' in userActivity.data);
```
`userActivity``data`属性值中的`online`属性应该被设为`45`
`userActivity``data` 属性值中的 `online` 属性值应被改为 `45`
```js
assert(userActivity.data.online === 45);
```
你应该用点符号或者方括号符号来设置`online`属性。
应使用点号表示法或方括号表示法来修改 `online` 属性
```js
assert.strictEqual(code.search(/online: 45/), -1);

View File

@ -1,13 +1,13 @@
---
id: 587d78b2367417b2b2512b0f
title: 使用 pop() 和 shift() 从数组中删除项目
title: 使用 pop() 和 shift() 从数组中删除元素
challengeType: 1
forumTopicId: 301165
---
# --description--
`push()``unshift()`都分别有一个作用基本与之相反的函数:`pop()``shift()`你现在或许已经猜到,与插入元素相反,`pop()`从数组的末尾*移除*一个元素,而`shift()`从数组的开头移除一个元素。`pop()``shift()`与对应的`push()``unshift()`的关键区别在于,前者不能接受输入参数,而且每次只能修改数组中的一个元素。
`push()``unshift()` 都有一个与它们作用相反的函数:`pop()``shift()`。与插入元素相反,`pop()`从数组的末尾*移除*一个元素,而 `shift()`从数组的开头移除一个元素。`pop()``shift()``push()``unshift()` 的关键区别在于,用于删除元素的方法不接收参数,而且每次只能删除数组中的一个元素。
让我们来看以下的例子:
@ -15,27 +15,27 @@ forumTopicId: 301165
let greetings = ['whats up?', 'hello', 'see ya!'];
greetings.pop();
// now equals ['whats up?', 'hello']
// 数组现在是 ['whats up?', 'hello']
greetings.shift();
// now equals ['hello']
// 数组现在是 ['hello']
```
还可以用这些方法返回除的元素,像这样
这些用于删除数组元素的方法返回被删除的元素:
```js
let popped = greetings.pop();
// returns 'hello'
// greetings now equals []
// 返回 'hello',即 popped 的值为 'hello'
// greetings 数组现在为 []
```
# --instructions--
我们已经定义了一个`popShift`函数,它接收一个数组作为输入参数并返回一个新的数组。请修改这个函数,使用`pop()``shift()`来移除输入的数组的第一个元素和最后一个元素,并将这两个被移除的元素赋值给对应的变量,使得返回的数组包含它们的值。
我们已经定义了一个 `popShift` 函数,它接收一个数组作为输入参数并返回一个新的数组。请修改这个函数,使用 `pop()``shift()` 来移除输入的数组的第一个元素和最后一个元素,并将这两个被移除的元素分别赋值给对应的变量,使得最终返回的数组包含这两个值。
# --hints--
`popShift(["challenge", "is", "not", "complete"])`应返回`["challenge", "complete"]`
`popShift(["challenge", "is", "not", "complete"])` 应返回 `["challenge", "complete"]`
```js
assert.deepEqual(popShift(['challenge', 'is', 'not', 'complete']), [
@ -44,13 +44,13 @@ assert.deepEqual(popShift(['challenge', 'is', 'not', 'complete']), [
]);
```
`popShift`函数应使用`pop()`方法
`popShift` 函数应使用 `pop()` 方法
```js
assert.notStrictEqual(popShift.toString().search(/\.pop\(/), -1);
```
`popShift`函数应使用`shift()`方法
`popShift` 函数应使用 `shift()` 方法
```js
assert.notStrictEqual(popShift.toString().search(/\.shift\(/), -1);

View File

@ -1,46 +1,46 @@
---
id: 587d78b2367417b2b2512b10
title: 使用 splice() 删除项目
title: 使用 splice() 删除元素
challengeType: 1
forumTopicId: 301166
---
# --description--
上面的挑战中,我们已经学了如何`shift()``pop()`从数组的开头或末尾移除元素但如果我们想除数组中间的一个元素呢?或者想一次除多个元素呢?这时候我们就需要`splice()`了。`splice()`让我们可以从数组中的任意位置**除任意数量的连续的元素**。
之前的挑战中,我们已经学了如何用 `shift()``pop()` 从数组的开头或末尾移除元素但如果我们想除数组中间的一个元素或者想一次除多个元素,该如何操作呢?这时候我们就需要使用 `splice()` 方法了,`splice()` 可以让我们从数组中的任意位置**连续删除任意数量的元素**。
`splice()`最多可以接受 3 个参数,但现在我们先关注前两个。`splice()`接收的前两个参数基于调用`splice()`数组中元素索引。记住,数组的索引是*从 0 开始的**zero-indexed*,所以我们要用`0`来指示数组中的第一个元素。`splice()`的第一个参数代表从数组中的哪个索引开始移除元素,而第二个参数示要从数组中删除多少个元素。例如:
`splice()` 最多可以接受 3 个参数,但现在我们先关注前两个。`splice()` 接收的前两个参数调用 `splice()` 数组中元素索引作为参考。别忘了,数组的索引是*从 0 开始的*,所以我们要用 `0` 来表示数组中的第一个元素。`splice()` 的第一个参数代表从数组中的哪个索引开始移除元素,而第二个参数示要从数组中的这位位置删除多少个元素。例如:
```js
let array = ['today', 'was', 'not', 'so', 'great'];
array.splice(2, 2);
// 从第三个索引位置开始移除 2 个元素
// array 现在是 ['today', 'was', 'great']
// 从索引为 2 的位置(即第三个元素)开始移除 2 个元素
// array 的值现在是 ['today', 'was', 'great']
```
`splice()`不仅从被调用的数组中移除元素,还会返回一个包含被移除元素的数组:
`splice()` 不仅会修改调用该方法的数组,还会返回一个包含被移除元素的数组:
```js
let array = ['I', 'am', 'feeling', 'really', 'happy'];
let newArray = array.splice(3, 2);
// newArray 是 ['really', 'happy']
// newArray 的值是 ['really', 'happy']
```
# --instructions--
给定初始化的数组 `arr`。使用 `splice()``arr` 里移除元素,使剩余的元素和为 `10`
我们已经定义了数组 `arr`使用 `splice()``arr` 里移除元素,使剩余的元素和为 `10`
# --hints--
不应修改这一行 `const arr = [2, 4, 5, 1, 7, 5, 2, 1];`
不应修改这一行 `const arr = [2, 4, 5, 1, 7, 5, 2, 1];`
```js
assert(code.replace(/\s/g, '').match(/constarr=\[2,4,5,1,7,5,2,1\];?/));
```
`arr` 的剩余元素和应`10`
`ahr` 的剩余元素和应为 `10`
```js
assert.strictEqual(
@ -49,13 +49,13 @@ assert.strictEqual(
);
```
该利用 `arr` `splice()`
`arr` 调用 `splice()` 方法
```js
assert(code.replace(/\s/g, '').match(/arr\.splice\(/));
```
splice 应只删除 `arr` 里面的元素,不能给 `arr` 添加元素。
splice 应只删除 `arr` 里面的元素,不能给 `arr` 添加元素。
```js
assert(!code.replace(/\s/g, '').match(/arr\.splice\(\d+,\d+,\d+.*\)/g));

View File

@ -1,21 +1,21 @@
---
id: 587d7b7e367417b2b2512b20
title: 使用数组存储数据集合
title: 使用数组存储不同类型的数据
challengeType: 1
forumTopicId: 301167
---
# --description--
以下是<dfn>数组Array</dfn>数据结构的最简单的实现例子。这是一个<dfn>一维数组one-dimensional array</dfn>,它只有一层,或者说它里面没有包含其它数组结构。可以看到它里面包含了<dfn>布尔值booleans</dfn><dfn>字符串strings</dfn><dfn>数字numbers</dfn>以及一些其他的 JavaScript 语言中合法的数据类型:
以下是最简单的<dfn>数组Array</dfn>示例:这是一个<dfn>一维数组one-dimensional array</dfn>,它只有一层,或者说它里面没有包含其它数组。可以观察到,这个数组中只包含了<dfn>布尔值booleans</dfn><dfn>字符串strings</dfn><dfn>数字numbers</dfn>以及 JavaScript 中的其他数据类型:
```js
let simpleArray = ['one', 2, 'three', true, false, undefined, null];
console.log(simpleArray.length);
// logs 7
// 输出 7
```
可以在上述例子中看到,所有数组都有一个<dfn>长度length</dfn>属性。可以简单地使用`Array.length`方法来访问它。 下面是一个关于数组的更复杂的例子。这是一个<dfn>多维数组multi-dimensional Array</dfn>,或者说是一个包含了其他数组的数组。可以注意到,在它的内部还包含了 JavaScript <dfn>对象objects</dfn>结构。我们会在后面的小节中讨论该数据结构,但现在你只需要知道数组能够存储复杂的对象类型数据。
所有数组都有一个表示长度的属性,我们可以通过 `Array.length` 来访问它。接下来是一个稍复杂的数组示例:这是一个<dfn>多维数组multi-dimensional Array</dfn>,或者说是一个包含了其他数组的数组。可以观察到,在这个数组内部还包含了 JavaScript 的<dfn>对象objects</dfn>我们会在后面的挑战中详细讨论该数据结构现在你只需要知道数组能够存储复杂的对象数据。
```js
let complexArray = [
@ -44,35 +44,35 @@ let complexArray = [
# --instructions--
我们已经定义了一个名为`yourArray`的变量。请修改题目中的语句,将一个含有至少 5 个元素的数组赋值给`yourArray`变量。你的数组应包含至少一个 <dfn>string</dfn> 类型的数据、一个 <dfn>number</dfn> 类型的数据和一个 <dfn>boolean</dfn> 类型的数据。
我们已经定义了一个名为 `yourArray` 的变量。请修改代码,将一个含有至少 5 个元素的数组赋值给 `yourArray` 变量。你的数组应包含至少一个 <dfn>string</dfn> 类型的数据、一个 <dfn>number</dfn> 类型的数据和一个 <dfn>boolean</dfn> 类型的数据。
# --hints--
yourArray 应该是一个数组。
yourArray 应数组。
```js
assert.strictEqual(Array.isArray(yourArray), true);
```
`yourArray`至少要包含 5 个元素。
`yourArray` 应包含至少 5 个元素。
```js
assert.isAtLeast(yourArray.length, 5);
```
`yourArray`包含至少一个`boolean`
`yourArray` 应包含至少一个 `boolean`
```js
assert(yourArray.filter((el) => typeof el === 'boolean').length >= 1);
```
`yourArray`包含至少一个`number`
`yourArray` 应包含至少一个 `number`
```js
assert(yourArray.filter((el) => typeof el === 'number').length >= 1);
```
`yourArray`包含至少一个`string`
`yourArray` 应包含至少一个 `string`
```js
assert(yourArray.filter((el) => typeof el === 'string').length >= 1);

View File

@ -7,11 +7,11 @@ forumTopicId: 301168
# --description--
现在你已经知道什么是对象以及对象的基本特性和用途。总之,对象是以键值对的形式,灵活、直观地存储结构化数据的一种方式,***且***查找对象属性速度很快的。在本章下的挑战中,我们会讲对象的几种常用操作,这样你能更好地在你的程序中使用这有用的数据结构。
现在我们已经学习了什么是对象以及对象的基本特性和用途。总之,对象是以键值对的形式,灵活、直观地存储结构化数据的一种方式,***且***,通过对象属性查找属性值是速度很快的操作。在本章下的挑战中,我们来了解一下对象的几种常用操作,这样你能更好地在代码中使用这个十分有用的数据结构:对象
在之前的挑战中,我们已经试过新增和修改对象中的键值对。现在我们来看如何从一个对象中*移除*一个键值对。
在之前的挑战中,我们已经试过添加和修改对象中的键值对。现在我们来看如何从一个对象中*移除*一个键值对。
我们再来上一个挑战中的`foods`对象。如果我们想移除`apples`属性,我们可以使用`delete`关键字:
我们再来回顾一下上一个挑战中的 `foods` 对象。如果我们想移除 `apples` 属性,可以像这样使用 `delete` 关键字:
```js
delete foods.apples;
@ -19,11 +19,11 @@ delete foods.apples;
# --instructions--
用 delete 关键字来移除`foods`中的`oranges``plums``strawberries`属性。
使`delete` 关键字来移除 `foods` 中的 `oranges``plums``strawberries` 属性。
# --hints--
`foods`对象应该只含有 3 个`apples``grapes``bananas`
`foods` 对象应只包含 3 个属性`apples``grapes``bananas`
```js
assert(
@ -34,7 +34,7 @@ assert(
);
```
你应该用`delete`关键字来移除`oranges``plums``strawberries`属性。
应使用 `delete` 关键字来移除 `oranges``plums``strawberries` 属性。
```js
assert(