fix(i18n): update Chinese translation of basic data structures (#38054)
Co-authored-by: Zhicheng Chen <chenzhicheng@dayuwuxian.com>
This commit is contained in:
@ -2,15 +2,42 @@
|
||||
id: 5a661e0f1068aca922b3ef17
|
||||
title: Access an Array's Contents Using Bracket Notation
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用括号表示法访问数组的内容
|
||||
forumTopicId: 301149
|
||||
localeTitle: 使用方括号访问数组的内容
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">当然,任何数据结构的基本特征是不仅能够存储数据,而且能够根据命令检索该数据。所以,既然我们已经学会了如何创建数组,那么让我们开始考虑如何访问该数组的信息。当我们定义一个如下所示的简单数组时,其中有3个项目: <blockquote>让ourArray = [“a”,“b”,“c”]; </blockquote>在数组中,每个数组项都有一个<dfn>索引</dfn> 。此索引兼作数组中该项的位置,以及您如何引用它。但是,值得注意的是,JavaScript数组是<dfn>零索引的</dfn> ,这意味着数组的第一个元素实际上处于第<em><strong>零</strong></em>位,而不是第一个。为了从数组中检索元素,我们可以将一个索引括在括号中,并将其附加到数组的末尾,或者更常见的是附加到引用数组对象的变量。这称为<dfn>括号表示法</dfn> 。例如,如果我们想从<code>ourArray</code>检索<code>"a"</code>并将其分配给变量,我们可以使用以下代码执行此操作: <blockquote>让ourVariable = ourArray [0]; <br> // ourVariable等于“a” </blockquote>除了访问与索引相关的值,你还可以<em>设置</em>索引使用相同的符号中的值: <blockquote> ourArray [1] =“不再是b”; <br> // ourArray现在等于[“a”,“不再b”,“c”]; </blockquote>使用括号表示法,我们现在将索引1处的项目从<code>"b"</code>重置为<code>"not b anymore"</code> 。 </section>
|
||||
<section id='description'>
|
||||
所有数据结构的基本特性是,它们不仅能够存储数据,我们还能够按照需求来访问存放在其中的数据。我们已经学习了如何创建一个数组结构,现在让我们开始学习如何访问这个数组结构中的数据。
|
||||
我们先定义一个包含 3 个元素的数组:
|
||||
|
||||
```js
|
||||
let ourArray = ["a", "b", "c"];
|
||||
```
|
||||
|
||||
在一个数组结构中,其内部的每个元素都有一个与之对应的<dfn>索引</dfn>(<dfn>index</dfn>)。索引是该元素在数组中的位置,可被用于引用该元素。但需要注意的是,JavaScript 数组的索引是从0开始的(<dfn>zero-indexed</dfn>),即一个数组的第一个元素是在数组中的<em><strong>第 0 个</strong></em>位置,而不是第 1 个位置。
|
||||
要从一个数组中获取一个元素,我们可以在一个数组变量名的后面加一个使用“方括号”括起来的索引。这叫做<dfn>方括号符号</dfn>(<dfn>bracket notation</dfn>)。
|
||||
例如我们要从<code>ourArray</code>数组变量中获取数据元素<code>"a"</code>并将其赋值给一个变量,我们可以编写如下所示的代码:
|
||||
|
||||
```js
|
||||
let ourVariable = ourArray[0];
|
||||
// ourVariable 的值为 "a"
|
||||
```
|
||||
|
||||
除了使用 “索引” 来获取某个元素值以外,你还可以通过类似的方法来<em>设置</em>一个索引位置所对应的元素值:
|
||||
|
||||
```js
|
||||
ourArray[1] = "not b anymore";
|
||||
// ourArray 现在的值为 ["a", "not b anymore", "c"];
|
||||
```
|
||||
|
||||
我们现在已经利用方括号将索引为 1 的元素从<code>"b"</code>设置为了<code>"not b anymore"</code>。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">为了完成此挑战,将<code>myArray</code>的第二个位置(索引<code>1</code> )设置为您想要的任何内容,除了<code>"b"</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
在本挑战中,请你将<code>myArray</code>中第二个元素(索引<code>1</code>)设置为除了<code>"b"</code>以外的任意值。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
@ -41,7 +68,6 @@ let myArray = ["a", "b", "c", "d"];
|
||||
|
||||
//change code above this line
|
||||
console.log(myArray);
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -55,5 +81,8 @@ console.log(myArray);
|
||||
|
||||
```js
|
||||
// solution required
|
||||
let myArray = ["a", "b", "c", "d"];
|
||||
myArray[1] = "e";
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,15 +2,26 @@
|
||||
id: 587d7b7c367417b2b2512b1a
|
||||
title: Access Property Names with Bracket Notation
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用括号表示法访问属性名称
|
||||
forumTopicId: 301150
|
||||
localeTitle: 使用方括号访问属性名称
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">在第一个对象挑战中,我们提到使用括号表示法作为使用变量求值来访问属性值的方法。例如,假设我们的<code>foods</code>对象被用于超市收银机的程序中。我们有一些设置<code>selectedFood</code>功能,我们想检查我们的<code>foods</code>对象是否存在该食物。这可能看起来像: <blockquote> let selectedFood = getCurrentFood(scanningItem); <br>让库存=食物[selectedFood]; </blockquote>此代码将评估存储在<code>selectedFood</code>变量中的值,并在<code>foods</code>对象中返回该键的值,如果不存在则返回<code>undefined</code> 。括号表示法非常有用,因为有时候对象属性在运行时之前是未知的,或者我们需要以更动态的方式访问它们。 </section>
|
||||
<section id='description'>
|
||||
在关于对象的第一个挑战中,我们提到可以在方括号符号中用一个变量作为属性名来访问属性值。假设一个超市的收银台的程序中使用了一个<code>foods</code>对象,并且有一些程序逻辑会设置<code>selectedFood</code>,我们需要查询<code>foods</code>对象来检查某种食物是否存在,我们可以这样写检查逻辑:
|
||||
|
||||
```js
|
||||
let selectedFood = getCurrentFood(scannedItem);
|
||||
let inventory = foods[selectedFood];
|
||||
```
|
||||
|
||||
上述代码会先计算<code>selectedFood</code>变量的值,并返回<code>foods</code>对象中以该值命名的属性对应的值,若没有以该值命名的属性则会返回<code>undefined</code>。有时候对象的属性名在运行之前是不确定的,或者我们需要动态地访问对象的属性,这时方括号符号就会很有用。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">我们定义了一个函数<code>checkInventory</code> ,它接收一个扫描的项目作为参数。返回<code>foods</code>对象中的<code>scannedItem</code>键的当前值。您可以假设只有有效键将作为<code>checkInventory</code>的参数提供。 </section>
|
||||
<section id='instructions'>
|
||||
我们已经定义了一个<code>checkInventory</code>函数,它接受一个被扫描到的商品名作为输入参数。它要返回<code>foods</code>对象中以<code>scannedItem</code>的值命名的属性的值。只有有效的属性名会作为参数传入<code>checkInventory</code>,你在完成挑战时不需处理参数无效的情况。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
@ -55,7 +66,6 @@ function checkInventory(scannedItem) {
|
||||
|
||||
// change code below this line to test different cases:
|
||||
console.log(checkInventory("apples"));
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -69,5 +79,18 @@ console.log(checkInventory("apples"));
|
||||
|
||||
```js
|
||||
// solution required
|
||||
let foods = {
|
||||
apples: 25,
|
||||
oranges: 32,
|
||||
plums: 28,
|
||||
bananas: 13,
|
||||
grapes: 35,
|
||||
strawberries: 27
|
||||
};
|
||||
|
||||
function checkInventory(scannedItem) {
|
||||
return foods[scannedItem];
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,15 +2,32 @@
|
||||
id: 587d78b2367417b2b2512b0e
|
||||
title: Add Items to an Array with push() and unshift()
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用push()和unshift()将项添加到数组
|
||||
forumTopicId: 301151
|
||||
localeTitle: 使用 push() 和 unshift() 添加项目到数组中
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">数组的长度与它可以包含的数据类型一样,并不固定。可以使用任意数量的元素的长度来定义数组,并且可以随时间添加或移除元素;换句话说,数组是<dfn>可变的</dfn> 。在这个挑战中,我们将研究两种方法,我们可以用它们以编程方式修改数组: <code>Array.push()</code>和<code>Array.unshift()</code> 。两种方法都将一个或多个元素作为参数,并将这些元素添加到调用该方法的数组中; <code>push()</code>方法将元素添加到数组的末尾, <code>unshift()</code>将元素添加到开头。考虑以下: <blockquote>让二十三'='XXIII'; <br>让romanNumerals = ['XXI','XXII']; <br><br> romanNumerals.unshift('XIX','XX'); <br> //现在等于['XIX','XX','XXI','XXII'] <br><br> romanNumerals.push(二十三); <br> //现在等于['XIX','XX','XXI','XXII','XXIII']请注意,我们也可以传递变量,这使我们可以更灵活地动态修改数组的数据。 </blockquote></section>
|
||||
<section id='description'>
|
||||
一个数组的长度与其包含的数据类型一样,是不固定的。数组可以包含任意数量的元素,可以不限次数地往数组中添加元素或者从中移除元素,或者说数组是<dfn>可变的</dfn>(<dfn>mutable</dfn>)。在本挑战中,我们要学习两个以编程方式修改数组的方法:<code>Array.push()</code>和<code>Array.unshift()</code>。
|
||||
这两个方法都接收一个或多个元素作为参数;对一个数组调用这两个方法都可以将输入的元素插入到该数组中;<code>push()</code>方法将元素插入到一个数组的末尾,而<code>unshift()</code>方法将元素插入到一个数组的开头。请看以下例子:
|
||||
|
||||
```js
|
||||
let twentyThree = 'XXIII';
|
||||
let romanNumerals = ['XXI', 'XXII'];
|
||||
|
||||
romanNumerals.unshift('XIX', 'XX');
|
||||
// 数组现在为 ['XIX', 'XX', 'XXI', 'XXII']
|
||||
|
||||
romanNumerals.push(twentyThree);
|
||||
// 数组现在为 ['XIX', 'XX', 'XXI', 'XXII', 'XXIII']
|
||||
```
|
||||
注意,我们还可以输入变量,这允许我们很灵活地动态改变我们数组中的数据。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">我们定义了一个函数<code>mixedNumbers</code> ,我们将一个数组作为参数传递。修改函数使用<code>push()</code>和<code>unshift()</code>将<code>'I', 2, 'three'</code>到数组的开头,将<code>7, 'VIII', 9</code>到结尾,以便返回的数组包含数字的表示形式按顺序1-9。 </section>
|
||||
<section id='instructions'>
|
||||
我们已经定义了一个<code>mixedNumbers</code>函数,它会接受一个数组作为参数。请你修改这个函数,使用<code>push()</code>和<code>unshift()</code>来将<code>'I', 2, 'three'</code>插入到数组的开头,将<code>7, 'VIII', 9</code>插入到数组的末尾,使得这个函数返回一个依次包含 1-9 的数组。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
@ -43,7 +60,6 @@ function mixedNumbers(arr) {
|
||||
|
||||
// do not change code below this line
|
||||
console.log(mixedNumbers(['IV', 5, 'six']));
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -56,6 +72,13 @@ console.log(mixedNumbers(['IV', 5, 'six']));
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
function mixedNumbers(arr) {
|
||||
// change code below this line
|
||||
arr.push(7,'VIII',9);
|
||||
arr.unshift('I',2,'three');
|
||||
// change code above this line
|
||||
return arr;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,15 +2,32 @@
|
||||
id: 587d78b3367417b2b2512b11
|
||||
title: Add Items Using splice()
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用splice()添加项目
|
||||
forumTopicId: 301152
|
||||
localeTitle: 使用 splice() 增加项目
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">还记得在上一次挑战中我们提到过<code>splice()</code>最多需要三个参数吗?好吧,我们可以更进一步使用<code>splice()</code> - 除了删除元素之外,我们还可以使用代表一个或多个元素的第三个参数来<em>添加</em>它们。这对于快速切换另一个元素或一组元素非常有用。例如,假设您正在为数组中的一组DOM元素存储颜色方案,并希望根据某些操作动态更改颜色: <blockquote> function colorChange(arr,index,newColor){ <br> arr.splice(index,1,newColor); <br>返回<br> } <br><br>让colorScheme = ['#878787','#a08794','#bb7e8c','#c9b6be','#d1becf']; <br><br> colorScheme = colorChange(colorScheme,2,'#332327'); <br> //我们删除了'#bb7e8c'并在其位置添加了'#332327' <br> // colorScheme现在等于['#878787','#a08794','#332327','#c9b6be','#d1becf'] </blockquote>此函数采用十六进制值数组,删除元素的索引以及用于替换已删除元素的新颜色。返回值是一个包含新修改的颜色方案的数组!虽然这个例子有点过于简单,但我们可以看到利用<code>splice()</code>到其最大潜力的值。 </section>
|
||||
<section id='description'>
|
||||
你还记得在上个挑战中我们提到<code>splice()</code>方法可以接受最多 3 个参数吗?我们现在可以进一步了解<code>splice()</code>。除了移除元素,我们还可以利用它的第三个参数来向数组中<em>添加</em>元素。第三个参数可以是一个或多个元素,这些元素会被添加到数组中。这使我们能够便捷地将数组中的一个或一系列元素换成其他的元素。例如:
|
||||
|
||||
```js
|
||||
const numbers = [10, 11, 12, 12, 15];
|
||||
const startIndex = 3;
|
||||
const amountToDelete = 1;
|
||||
|
||||
numbers.splice(startIndex, amountToDelete, 13, 14);
|
||||
// 第二个 12 被移除,在第二个 12 的索引处添加 13、14。
|
||||
console.log(numbers);
|
||||
// 返回 [ 10, 11, 12, 13, 14, 15 ]
|
||||
```
|
||||
|
||||
以一个数字数组开始。接着调用 <code>splice()</code> 方法,在 (3) 的索引位置开始删除元素,删除的元素数量是 (1),(13, 14) 是在删除位置插入的元素,可以在 <code>amountToDelete</code> 后面插入任意数量的元素(以逗号分隔),每个都会被插入。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">我们定义了一个函数<code>htmlColorNames</code> ,它将一组HTML颜色作为参数。使用<code>splice()</code>修改函数以删除数组的前两个元素,并在各自的位置添加<code>'DarkSalmon'</code>和<code>'BlanchedAlmond'</code> <code>'DarkSalmon'</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
我们已经定义了一个<code>htmlColorNames</code>函数,它以一个 HTML 颜色的数组作为输入参数。请修改这个函数,利用<code>splice()</code>来移除数组中的前两个元素,并在对应的位置上添加<code>'DarkSalmon'</code>和<code>'BlanchedAlmond'</code>。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
@ -45,7 +62,6 @@ function htmlColorNames(arr) {
|
||||
|
||||
// do not change code below this line
|
||||
console.log(htmlColorNames(['DarkGoldenRod', 'WhiteSmoke', 'LavenderBlush', 'PaleTurqoise', 'FireBrick']));
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -58,6 +74,10 @@ console.log(htmlColorNames(['DarkGoldenRod', 'WhiteSmoke', 'LavenderBlush', 'Pal
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
function htmlColorNames(arr) {
|
||||
arr.splice(0,2,'DarkSalmon', 'BlanchedAlmond');
|
||||
return arr;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,30 +2,59 @@
|
||||
id: 587d7b7c367417b2b2512b18
|
||||
title: Add Key-Value Pairs to JavaScript Objects
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 将键值对添加到JavaScript对象
|
||||
forumTopicId: 301153
|
||||
localeTitle: 将键值对添加到对象中
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">在最基本的情况下,对象只是<dfn>键值对的</dfn>集合,换句话说,映射到我们称为<dfn>属性</dfn>或<dfn>键的</dfn>唯一标识符的数据片段。我们来看一个非常简单的例子: <blockquote>让FCC_User = { <br>用户名:'awesome_coder', <br>粉丝:572, <br>积分:1741, <br>已完成项目:15 <br> }; </blockquote>上面的代码定义了一个名为<code>FCC_User</code>的对象,它有四个<dfn>属性</dfn> ,每个<dfn>属性</dfn>都映射到一个特定的值。如果我们想知道的数量<code>followers</code> <code>FCC_User</code>了,我们可以通过写访问属性: <blockquote> let userData = FCC_User.followers; <br> // userData等于572 </blockquote>这称为<dfn>点符号</dfn> 。或者,我们也可以使用括号访问该属性,如下所示: <blockquote>让userData = FCC_User ['粉丝'] <br> // userData等于572 </blockquote>请注意,带<dfn>支架的符号</dfn> ,我们封闭<code>followers</code>在引号。这是因为括号实际上允许我们传递一个变量以作为属性名称进行评估(提示:请记住这一点以供日后使用!)。如果我们在没有引号的情况下传递了<code>followers</code> ,那么JavaScript引擎会尝试将其作为变量进行评估,而<code>ReferenceError: followers is not defined</code>将被抛出。 </section>
|
||||
<section id='description'>
|
||||
对象(object)本质上是<dfn>键值对(key-value pair)</dfn>的集合,或者说,一系列被映射到唯一标识符(叫做<dfn>属性(property)</dfn>或者<dfn>键(key)</dfn>)的数据。让我们来看一个很简单的例子:
|
||||
|
||||
```js
|
||||
let FCC_User = {
|
||||
username: 'awesome_coder',
|
||||
followers: 572,
|
||||
points: 1741,
|
||||
completedProjects: 15
|
||||
};
|
||||
```
|
||||
|
||||
上面的代码定义了一个叫做<code>FCC_User</code>的对象,它有 4 个<dfn>属性</dfn>,每个属性映射一个特定的值。如果我们想知道<code>FCC_User</code>有多少<code>followers</code>,我们可以这样访问其<code>followers</code>属性:
|
||||
|
||||
```js
|
||||
let userData = FCC_User.followers;
|
||||
// userData 等于 572
|
||||
```
|
||||
|
||||
这叫做<dfn>点符号(dot notation)</dfn>。我们还可以用方括号符号来访问对象中的属性:
|
||||
|
||||
```js
|
||||
let userData = FCC_User['followers'];
|
||||
// userData 等于 572
|
||||
```
|
||||
|
||||
注意,在用<dfn>方括号符号</dfn>时,我们在括号里写的是字符串<code>followers</code>(用引号括起)。方括号符号让我们能用一个变量作为属性名来访问对象的属性(请记住)。若我们在方括号中不写引号而直接写<code>followers</code>,JavaScript 引擎会将其看作一个变量,并抛出一个<code>ReferenceError: followers is not defined</code>的错误。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">使用相同的语法,我们还<em><strong>可以</strong></em>向对象<em><strong>添加新的</strong></em>键值对。我们用三个条目创建了一个<code>foods</code>对象。再添加三个条目:价值为<code>13</code> <code>bananas</code> ,价值为<code>35</code> <code>grapes</code>和价值为<code>27</code> <code>strawberries</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
用这样的语法,我们还可以向对象中<em><strong>新增</strong></em>键值对。我们已经创建了一个有 3 个属性的<code>foods</code>对象,请为其新增 3 项:值为<code>13</code>的<code>bananas</code>属性、值为<code>35</code>的<code>grapes</code>属性和值为<code>27</code>的<code>strawberries</code>属性。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>foods</code>是一个对象
|
||||
- text: <code>foods</code>应该是一个对象。
|
||||
testString: assert(typeof foods === 'object');
|
||||
- text: <code>foods</code>对象有一个值为<code>13</code>的关键<code>"bananas"</code>
|
||||
- text: <code>foods</code>应该有一个值为<code>13</code>的<code>"bananas"</code>属性。
|
||||
testString: assert(foods.bananas === 13);
|
||||
- text: <code>foods</code>对象有一个关键的<code>"grapes"</code> ,价值<code>35</code>
|
||||
- text: <code>foods</code>应该有一个值为<code>35</code>的<code>"grapes"</code>属性。
|
||||
testString: assert(foods.grapes === 35);
|
||||
- text: <code>foods</code>对象有一个关键的<code>"strawberries"</code> ,值为<code>27</code>
|
||||
- text: <code>foods</code>应该有一个值为<code>27</code>的<code>"strawberries"</code>属性。
|
||||
testString: assert(foods.strawberries === 27);
|
||||
- text: 应使用点或括号表示法设置键值对
|
||||
- text: 你应该用点符号或者方括号符号来设置对象的属性。
|
||||
testString: assert(code.search(/bananas:/) === -1 && code.search(/grapes:/) === -1 && code.search(/strawberries:/) === -1);
|
||||
|
||||
```
|
||||
@ -49,7 +78,6 @@ let foods = {
|
||||
// change code above this line
|
||||
|
||||
console.log(foods);
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -62,6 +90,17 @@ console.log(foods);
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
let foods = {
|
||||
apples: 25,
|
||||
oranges: 32,
|
||||
plums: 28
|
||||
};
|
||||
|
||||
// change code below this line
|
||||
foods['bananas'] = 13;
|
||||
foods['grapes'] = 35;
|
||||
foods['strawberries'] = 27;
|
||||
// change code above this line
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,15 +2,29 @@
|
||||
id: 587d7b7b367417b2b2512b14
|
||||
title: Check For The Presence of an Element With indexOf()
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用indexOf()检查元素是否存在
|
||||
forumTopicId: 301154
|
||||
localeTitle: 使用 indexOf() 检查元素是否存在
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">由于数组可以随时更改或<em>变异</em> ,因此无法保证特定数据在特定数组中的位置,或者该元素是否仍然存在。幸运的是,JavaScript为我们提供了另一种内置方法<code>indexOf()</code> ,它允许我们快速,轻松地检查数组中元素的存在。 <code>indexOf()</code>接受一个元素作为参数,并在调用时返回该元素的位置或索引,如果该元素在数组中不存在,则返回<code>-1</code> 。例如: <blockquote>让水果= ['苹果','梨','橙子','桃子','梨子']; <br><br> fruits.indexOf('dates')//返回-1 <br> fruits.indexOf('oranges')//返回2 <br> fruits.indexOf('pears')//返回1,元素所在的第一个索引</blockquote></section>
|
||||
<section id='description'>
|
||||
由于数组可以在任意时间被修改或者说<em>被改变(mutated)</em>,我们不能保证某个数据在一个给定数组中的位置,甚至不能保证该元素还存在于该数组中。幸运的是,JavaScript 给我们提供了另一个内置方法<code>indexOf()</code>。这个方法让我们可以便捷地检查某个元素是否存在于一个数组中。<code>indexOf()</code>方法接受一个元素作为输入参数,并返回该元素在数组中的位置(索引);若该元素不存在于数组中则返回<code>-1</code>。
|
||||
例如:
|
||||
|
||||
```js
|
||||
let fruits = ['apples', 'pears', 'oranges', 'peaches', 'pears'];
|
||||
|
||||
fruits.indexOf('dates'); // 返回 -1
|
||||
fruits.indexOf('oranges'); // 返回 2
|
||||
fruits.indexOf('pears'); // 返回 1,即第一个出现的 'pears' 元素在数组中的索引为 1
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions"> <code>indexOf()</code>对于快速检查数组中是否存在元素非常有用。我们定义了一个函数<code>quickCheck</code> ,它将一个数组和一个元素作为参数。使用<code>indexOf()</code>修改函数,以便在传递的元素存在于数组时返回<code>true</code>如果不存在则返回<code>false</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
<code>indexOf()</code>在快速检查一个数组中是否存在某个元素时非常有用。我们已经定义了一个<code>quickCheck</code>函数,它接受一个数组和一个元素作为输入参数。请修改这个函数,利用<code>indexOf()</code>方法,使得当输入的数组中含有输入的元素时,函数返回<code>true</code>;不含有输入的元素时,函数返回<code>false</code>。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
@ -46,7 +60,6 @@ function quickCheck(arr, elem) {
|
||||
|
||||
// change code here to test different cases:
|
||||
console.log(quickCheck(['squash', 'onions', 'shallots'], 'mushrooms'));
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -59,6 +72,11 @@ console.log(quickCheck(['squash', 'onions', 'shallots'], 'mushrooms'));
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
function quickCheck(arr, elem) {
|
||||
// change code below this line
|
||||
return arr.indexOf(elem) >= 0;
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,33 +2,49 @@
|
||||
id: 587d7b7d367417b2b2512b1c
|
||||
title: Check if an Object has a Property
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 检查对象是否具有属性
|
||||
forumTopicId: 301155
|
||||
localeTitle: 检查对象是否具有某个属性
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">现在我们可以添加,修改和删除对象中的键。但是,如果我们只是想知道某个对象是否具有特定属性呢? JavaScript为我们提供了两种不同的方法。一个使用<code>hasOwnProperty()</code>方法,另一个使用<code>in</code>关键字。如果我们有一个具有<code>Alan</code>属性的对象<code>users</code> ,我们可以通过以下任一方式检查其存在: <blockquote> users.hasOwnProperty( '艾伦'); <br> '艾伦'在用户; <br> //都返回true </blockquote></section>
|
||||
<section id='description'>
|
||||
现在我们可以新增、修改和移除对象中的属性。但如果我们想知道一个对象中是否含有某个属性呢?JavaScript 为我们提供了两种不同的方式来实现这个功能,一个是<code>hasOwnProperty()</code>方法,另一个是<code>in</code>关键字。如果我们有一个<code>users</code>对象,它有一个<code>Alan</code>属性,我们可以用以下两种方式之一来检查该属性在对象中是否存在:
|
||||
|
||||
```js
|
||||
users.hasOwnProperty('Alan');
|
||||
'Alan' in users;
|
||||
// 都返回 true
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">我们创建了一个对象, <code>users</code> ,其中包含一些用户和一个函数<code>isEveryoneHere</code> ,我们将<code>users</code>对象作为参数传递给它。完成编写此函数,以便仅当<code>users</code>对象包含所有四个名称( <code>Alan</code> , <code>Jeff</code> , <code>Sarah</code>和<code>Ryan</code> )作为键时才返回<code>true</code> ,否则返回<code>false</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
我们已经创建了一个含有一些用户的<code>users</code>对象和一个<code>isEveryoneHere</code>函数,该函数接受<code>users</code>对象作为参数。请完成该函数使其在<code>users</code>对象中包含以下 4 个键<code>Alan</code>、<code>Jeff</code>、<code>Sarah</code>和<code>Ryan</code>时才返回<code>true</code>,否则返回<code>false</code>。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>users</code>对象仅包含<code>Alan</code> , <code>Jeff</code> , <code>Sarah</code>和<code>Ryan</code>
|
||||
testString: 'assert("Alan" in users && "Jeff" in users && "Sarah" in users && "Ryan" in users && Object.keys(users).length === 4, "The <code>users</code> object only contains the keys <code>Alan</code>, <code>Jeff</code>, <code>Sarah</code>, and <code>Ryan</code>");'
|
||||
- text: 如果<code>Alan</code> , <code>Jeff</code> , <code>Sarah</code>和<code>Ryan</code>是<code>users</code>对象的属性,则函数<code>isEveryoneHere</code>返回<code>true</code>
|
||||
testString: 'assert(isEveryoneHere(users) === true, "The function <code>isEveryoneHere</code> returns <code>true</code> if <code>Alan</code>, <code>Jeff</code>, <code>Sarah</code>, and <code>Ryan</code> are properties on the <code>users</code> object");'
|
||||
- text: 如果<code>Alan</code> , <code>Jeff</code> , <code>Sarah</code>和<code>Ryan</code>不是<code>users</code>对象的属性,则函数<code>isEveryoneHere</code>返回<code>false</code>
|
||||
testString: 'assert((function() { delete users.Alan; delete users.Jeff; delete users.Sarah; delete users.Ryan; return isEveryoneHere(users) })() === false, "The function <code>isEveryoneHere</code> returns <code>false</code> if <code>Alan</code>, <code>Jeff</code>, <code>Sarah</code>, and <code>Ryan</code> are not properties on the <code>users</code> object");'
|
||||
|
||||
- text: <code>users</code>对象应该只含有<code>Alan</code>、<code>Jeff</code>、<code>Sarah</code>和<code>Ryan</code>4 个键。
|
||||
testString: assert("Alan" in users && "Jeff" in users && "Sarah" in users && "Ryan" in users && Object.keys(users).length === 4);
|
||||
- text: <code>isEveryoneHere</code>函数在<code>users</code>对象包含<code>Alan</code>、<code>Jeff</code>、<code>Sarah</code>和<code>Ryan</code>4 个键时应该返回<code>true</code>。
|
||||
testString: assert(isEveryoneHere(users) === true);
|
||||
- text: <code>isEveryoneHere</code>函数在<code>users</code>对象不包含<code>Alan</code>、<code>Jeff</code>、<code>Sarah</code>或<code>Ryan</code>4 个键时应该返回<code>false</code>。
|
||||
testString: assert((function() { delete users.Alan; return isEveryoneHere(users) })() === false);
|
||||
- text: 如果 <code>Jeff</code> 不是 <code>users</code> 对象的属性,函数 <code>isEveryoneHere</code> 应该返回 <code>false</code>。
|
||||
testString: assert((function() { delete users.Jeff; return isEveryoneHere(users) })() === false);
|
||||
- text: 如果 <code>Sarah</code> 不是 <code>users</code> 对象的属性,函数 <code>isEveryoneHere</code> 应该返回 <code>false</code>。
|
||||
testString: assert((function() { delete users.Sarah; return isEveryoneHere(users) })() === false);
|
||||
- text: 如果 <code>Ryan</code> 不是 <code>users</code> 对象的属性,函数 <code>isEveryoneHere</code> 应该返回 <code>false</code>。
|
||||
testString: assert((function() { delete users.Ryan; return isEveryoneHere(users) })() === false);
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
# Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
@ -60,7 +76,6 @@ function isEveryoneHere(obj) {
|
||||
}
|
||||
|
||||
console.log(isEveryoneHere(users));
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -73,6 +88,35 @@ console.log(isEveryoneHere(users));
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
let users = {
|
||||
Alan: {
|
||||
age: 27,
|
||||
online: true
|
||||
},
|
||||
Jeff: {
|
||||
age: 32,
|
||||
online: true
|
||||
},
|
||||
Sarah: {
|
||||
age: 48,
|
||||
online: true
|
||||
},
|
||||
Ryan: {
|
||||
age: 19,
|
||||
online: true
|
||||
}
|
||||
};
|
||||
|
||||
function isEveryoneHere(obj) {
|
||||
return [
|
||||
'Alan',
|
||||
'Jeff',
|
||||
'Sarah',
|
||||
'Ryan'
|
||||
].every(i => obj.hasOwnProperty(i));
|
||||
}
|
||||
|
||||
console.log(isEveryoneHere(users));
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,15 +2,28 @@
|
||||
id: 587d7b7b367417b2b2512b17
|
||||
title: Combine Arrays with the Spread Operator
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 将数组与Spread运算符组合在一起
|
||||
forumTopicId: 301156
|
||||
localeTitle: 组合使用数组和扩展运算符
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description"> <dfn>扩展</dfn>运算符的另一个巨大优势是能够组合数组,或者在任何索引处将一个数组的所有元素插入到另一个数组中。使用更传统的语法,我们可以连接数组,但这只允许我们在一个数组的末尾和另一个数组的开头组合数组。 Spread语法使以下操作非常简单: <blockquote>让thisArray = ['sage','迷迭香','欧芹','百里香']; <br><br>让那个阵容= ['罗勒','香菜',......这个阿雷,'香菜']; <br> //现在等于['罗勒','香菜','鼠尾草','迷迭香','欧芹','百里香','香菜'] </blockquote>使用扩展语法,我们刚刚实现了一个操作,如果我们使用传统方法,这个操作会更复杂,更冗长。 </section>
|
||||
<section id='description'>
|
||||
<dfn>展开运算符</dfn>的另一个大用处是合并数组,或者将某个数组的所有元素插入到另一个数组的任意位置。用传统的语法我们也可以连接两个数组,但只能两个数组首尾相接。而展开语法能使下面的操作变得极其简单:
|
||||
|
||||
```js
|
||||
let thisArray = ['sage', 'rosemary', 'parsley', 'thyme'];
|
||||
|
||||
let thatArray = ['basil', 'cilantro', ...thisArray, 'coriander'];
|
||||
// thatArray 现在是 ['basil', 'cilantro', 'sage', 'rosemary', 'parsley', 'thyme', 'coriander']
|
||||
```
|
||||
|
||||
使用展开语法,我们这样就实现了一个用传统方法要写得很复杂冗长的操作。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">我们定义了一个函数<code>spreadOut</code> ,它返回变量<code>sentence</code> ,使用<dfn>spread</dfn>运算符修改函数,使它返回数组<code>['learning', 'to', 'code', 'is', 'fun']</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
我们已经定义了一个返回<code>sentence</code>变量的<code>spreadOut</code>函数,请修改该函数,利用<dfn>展开运算符</dfn>使该函数返回数组<code>['learning', 'to', 'code', 'is', 'fun']</code>。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
@ -19,7 +32,7 @@ localeTitle: 将数组与Spread运算符组合在一起
|
||||
tests:
|
||||
- text: '<code>spreadOut</code>应该返回<code>["learning", "to", "code", "is", "fun"]</code>'
|
||||
testString: assert.deepEqual(spreadOut(), ['learning', 'to', 'code', 'is', 'fun']);
|
||||
- text: <code>spreadOut</code>函数应该使用扩展语法
|
||||
- text: <code>spreadOut</code>函数里应该用到展开语法
|
||||
testString: assert.notStrictEqual(spreadOut.toString().search(/[...]/), -1);
|
||||
|
||||
```
|
||||
@ -40,7 +53,6 @@ function spreadOut() {
|
||||
|
||||
// do not change code below this line
|
||||
console.log(spreadOut());
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -54,5 +66,13 @@ console.log(spreadOut());
|
||||
|
||||
```js
|
||||
// solution required
|
||||
|
||||
function spreadOut() {
|
||||
let fragment = ['to', 'code'];
|
||||
let sentence = ['learning', ...fragment, 'is', 'fun'];
|
||||
return sentence;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,30 +2,43 @@
|
||||
id: 587d7b7b367417b2b2512b13
|
||||
title: Copy an Array with the Spread Operator
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用Spread Operator复制数组
|
||||
forumTopicId: 301157
|
||||
localeTitle: 使用扩展运算符复制数组
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">虽然<code>slice()</code>允许我们选择要复制的数组元素,但在其他几个有用的任务中,ES6的新<dfn>扩展运算符</dfn>允许我们使用简单且高度可读的语法轻松地按顺序复制<em>所有</em>数组的元素。扩展语法看起来像这样: <code>...</code>在实践中,我们可以使用spread运算符来复制数组,如下所示: <blockquote> let thisArray = [true,true,undefined,false,null]; <br>让thatArray = [... thisArray]; <br> // thatArray等于[true,true,undefined,false,null] <br> // thisArray保持不变,与thatArray相同</blockquote></section>
|
||||
<section id='description'>
|
||||
<code>slice()</code>已经能让我们从一个数组中选择一些元素来复制到新数组中了,而 ES6 中又新引入了一个简洁且可读性强的语法<dfn>展开运算符(spread operator)</dfn>,它能让我们方便地复制数组中的<em>所有</em>元素。展开语法是这样的:<code>...</code>
|
||||
在实践中,我们可以这样用展开运算符来复制一个数组:
|
||||
|
||||
```js
|
||||
let thisArray = [true, true, undefined, false, null];
|
||||
let thatArray = [...thisArray];
|
||||
// thatArray 等于 [true, true, undefined, false, null]
|
||||
// thisArray 保持不变,等于 thatArray
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">我们定义了一个函数<code>copyMachine</code> ,它将<code>arr</code> (数组)和<code>num</code> (数字)作为参数。该函数应该返回一个由<code>arr</code>的<code>num</code>副本组成的新数组。我们为您完成了大部分工作,但它还没有正常工作。使用扩展语法修改函数以使其正常工作(提示:我们已经介绍过的另一种方法可能会派上用场!)。 </section>
|
||||
<section id='instructions'>
|
||||
我们已经定义了一个<code>copyMachine</code>函数,它接受<code>arr</code>(一个数组)和<code>num</code>(一个数字)作为输入参数。该函数应该返回一个由<code>num</code>个<code>arr</code>组成的新数组。我们已经为你写好了大部分的代码,但它还不能正确地工作。请修改这个函数,使用展开语法,使该函数正确工作(提示:我们已经学到过的一个方法很适合用在这里!)
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: '<code>copyMachine([true, false, true], 2)</code>应返回<code>[[true, false, true], [true, false, true]]</code>'
|
||||
- text: '<code>copyMachine([true, false, true], 2)</code>应该返回<code>[[true, false, true], [true, false, true]]</code>'
|
||||
testString: assert.deepEqual(copyMachine([true, false, true], 2), [[true, false, true], [true, false, true]]);
|
||||
- text: '<code>copyMachine([1, 2, 3], 5)</code>应返回<code>[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]</code>'
|
||||
- text: '<code>copyMachine([1, 2, 3], 5)</code>应该返回<code>[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]</code>'
|
||||
testString: assert.deepEqual(copyMachine([1, 2, 3], 5), [[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]);
|
||||
- text: '<code>copyMachine([true, true, null], 1)</code>应该返回<code>[[true, true, null]]</code>'
|
||||
testString: assert.deepEqual(copyMachine([true, true, null], 1), [[true, true, null]]);
|
||||
- text: '<code>copyMachine(["it works"], 3)</code>应该返回<code>[["it works"], ["it works"], ["it works"]]</code>'
|
||||
testString: assert.deepEqual(copyMachine(['it works'], 3), [['it works'], ['it works'], ['it works']]);
|
||||
- text: <code>copyMachine</code>函数应该使用带有数组<code>arr</code>的<code>spread operator</code>
|
||||
- text: <code>copyMachine</code>函数中应该对数组<code>arr</code>使用<code>spread operator</code>。
|
||||
testString: assert(removeJSComments(code).match(/\.\.\.arr/));
|
||||
|
||||
```
|
||||
@ -51,12 +64,18 @@ function copyMachine(arr, num) {
|
||||
|
||||
// change code here to test different cases:
|
||||
console.log(copyMachine([true, false, true], 2));
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
const removeJSComments = str => str.replace(/\/\*[\s\S]*?\*\/|\/\/.*$/gm, '');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
@ -64,6 +83,17 @@ console.log(copyMachine([true, false, true], 2));
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
function copyMachine(arr,num){
|
||||
let newArr=[];
|
||||
while(num >=1){
|
||||
// change code below this line
|
||||
newArr.push([...arr]);
|
||||
//change code above this line
|
||||
num--;
|
||||
}
|
||||
return newArr;
|
||||
}
|
||||
console.log(copyMachine([true, false, true], 2));
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,15 +2,29 @@
|
||||
id: 587d7b7a367417b2b2512b12
|
||||
title: Copy Array Items Using slice()
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用slice()复制数组项
|
||||
forumTopicId: 301158
|
||||
localeTitle: 使用 slice() 拷贝数组项目
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">我们将介绍的下一个方法是<code>slice()</code> 。 <code>slice()</code> ,而不是修改数组,将给定数量的元素复制或<em>提取</em>到新数组,而不改变它所调用的数组。 <code>slice()</code>只接受2个参数 - 第一个是开始提取的索引,第二个是停止提取的索引(提取将发生,但不包括此索引处的元素)。考虑一下: <blockquote>让weatherConditions = ['rain','snow','sleet','hail','clear']; <br><br>让todaysWeather = weatherConditions.slice(1,3); <br> //今天天气等于['雪','雨夹雪']; <br> // weatherConditions仍等于['rain','snow','sleet','hail','clear'] <br></blockquote>实际上,我们通过从现有数组中提取元素来创建一个新数组。 </section>
|
||||
<section id='description'>
|
||||
接下来我们要介绍<code>slice()</code>方法。<code>slice()</code>并不修改数组,而是复制或者说<em>提取(extract)</em>给定数量的元素到一个新数组里,而调用方法的数组则保持不变。<code>slice()</code>只接受 2 个输入参数—第一个是开始提取元素的位置(索引),第二个是结束提取元素的位置(索引)。slice 方法会提取直到截止索引的元素,但被提取的元素不包括截止索引对应的元素。请看以下例子:
|
||||
|
||||
```js
|
||||
let weatherConditions = ['rain', 'snow', 'sleet', 'hail', 'clear'];
|
||||
|
||||
let todaysWeather = weatherConditions.slice(1, 3);
|
||||
// todaysWeather 等于 ['snow', 'sleet'];
|
||||
// weatherConditions 仍然等于 ['rain', 'snow', 'sleet', 'hail', 'clear']
|
||||
```
|
||||
|
||||
现在我们从一个已有的数组中提取了一些元素,并用这些元素创建了一个新数组。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">我们定义了一个以数组作为参数的函数<code>forecast</code> 。使用<code>slice()</code>修改函数以从参数数组中提取信息,并返回包含元素<code>'warm'</code>和<code>'sunny'</code>的新数组。 </section>
|
||||
<section id='instructions'>
|
||||
我们已经定义了一个<code>forecast</code>函数,它接受一个数组作为参数。请修改这个函数,利用<code>slice()</code>来从输入的数组中提取信息,并返回一个包含元素<code>'warm'</code>和<code>'sunny'</code> 的新数组。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
@ -40,7 +54,6 @@ function forecast(arr) {
|
||||
|
||||
// do not change code below this line
|
||||
console.log(forecast(['cold', 'rainy', 'warm', 'sunny', 'cool', 'thunderstorms']));
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -53,6 +66,9 @@ console.log(forecast(['cold', 'rainy', 'warm', 'sunny', 'cool', 'thunderstorms']
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
function forecast(arr) {
|
||||
return arr.slice(2,4);
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,30 +2,72 @@
|
||||
id: 587d7b7b367417b2b2512b16
|
||||
title: Create complex multi-dimensional arrays
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301159
|
||||
localeTitle: 创建复杂的多维数组
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">真棒!你刚学了很多关于阵列的知识!这是一个相当高级别的概述,有很多关于使用数组的知识,其中大部分将在后面的章节中看到。但在继续观察<dfn>对象之前</dfn> ,让我们再看一下,看看阵列如何变得比我们在之前的挑战中看到的更复杂。将数组视为数据结构时,最强大的功能之一是数组可以包含甚至完全由其他数组组成。我们已经看到在之前的挑战中包含数组的数组,但相当简单。但是,数组可以包含无限深度的数组,这些数组可以包含其他数组,每个数组都有自己的任意深度级别,依此类推。通过这种方式,数组可以非常快速地变成非常复杂的数据结构,称为<dfn>多维</dfn>或嵌套数组。请考虑以下示例: <blockquote>让nestedArray = [// top,或first level - 最外面的数组<br> ['deep'],//数组中的数组,2个深度级别<br> [ <br> ['更深'],['更深'] // 2个数组嵌套3层深<br> ] <br> [ <br> [ <br> ['deepest'],['最深'] // 2个数组嵌套了4个级别<br> ] <br> [ <br> [ <br> ['deepest-est?'] //一个数组嵌套5层深<br> ] <br> ] <br> ] <br> ]。 </blockquote>虽然这个例子看似令人费解,但在处理大量数据时,这种复杂程度并非闻所未闻,甚至不同寻常。但是,我们仍然可以使用括号表示法轻松访问此复杂数组的最深层次: <blockquote>的console.log(nestedArray [2] [1] [0] [0] [0]); <br> //日志:最深? </blockquote>现在我们知道那条数据在哪里,如果需要,我们可以重置它: <blockquote> nestedArray [2] [1] [0] [0] [0] =“更深”; <br><br>的console.log(nestedArray [2] [1] [0] [0] [0]); <br> //现在记录:更深入</blockquote></section>
|
||||
<section id='description'>
|
||||
很好!你已经学到很多关于数组的知识了!但这些只是一个开始,你将在接下来的小节中学习到与数组相关的更多知识。但在继续去学习<dfn>对象</dfn>(<dfn>Objects</dfn>)之前,让我们再花一点时间看一看,数组怎样能够变得比之前的挑战中更复杂一点。
|
||||
数组的一个强大的特性是,它可以包含其他数组,甚至完全由其他数组组成。我们已经在上一个挑战中看到了包含数组的数组,但它还算是比较简单的。数组中的数组还可以在包含其他数组,数组中是可以嵌套任意层的数组的。数组从而可以被用来实现非常复杂的叫做<dfn>多维(multi-dimensional)</dfn>或嵌套(nested)数组的数据结构。请看如下例子:
|
||||
|
||||
```js
|
||||
let nestedArray = [ // 顶层,或第 1 层——最外层的数组
|
||||
['deep'], // 数组中的数组,第 2 层
|
||||
[
|
||||
['deeper'], ['deeper'] // 第 3 层嵌套的两个数组
|
||||
],
|
||||
[
|
||||
[
|
||||
['deepest'], ['deepest'] // 第 4 层嵌套的两个数组
|
||||
],
|
||||
[
|
||||
[
|
||||
['deepest-est?'] // 第 5 层嵌套的一个数组
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
虽然这个例子看起来错综复杂,但这样复杂的数组并不算罕见,尤其是在处理大量数据的时候。
|
||||
但我们仍能简单地用方括号符号来访问到嵌套得最深的数组:
|
||||
|
||||
```js
|
||||
console.log(nestedArray[2][1][0][0][0]);
|
||||
// logs: deepest-est?
|
||||
```
|
||||
|
||||
既然我们知道数据在哪里,我们就能修改它:
|
||||
|
||||
```js
|
||||
nestedArray[2][1][0][0][0] = 'deeper still';
|
||||
|
||||
console.log(nestedArray[2][1][0][0][0]);
|
||||
// now logs: deeper still
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">我们已经定义了一个变量<code>myNestedArray</code> ,它等于一个数组。修改<code>myNestedArray</code> ,使用数据元素的<dfn>字符串</dfn> , <dfn>数字</dfn>和<dfn>布尔值的</dfn>任意组合,以便它具有五个深度级别(请记住,最外层的数组是级别1)。某处在第三级上,包括字符串<code>'deep'</code> ,在第四级,包括字符串<code>'deeper'</code> ,并且在第五层上,包括字符串<code>'deepest'</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
我们已经定义了一个<code>myNestedArray</code>数组变量。请修改<code>myNestedArray</code>,用<dfn>字符串(string)</dfn>、<dfn>数字(number)</dfn>或者<dfn>布尔值(boolean)</dfn>作为数组的数据元素,使得<code>myNestedArray</code>刚好有 5 层数组嵌套(记住,最外层的数组是第 1 层)。请在第 3 层的数组中包含字符串<code>'deep'</code>,在第 4 层的数组中包含字符串<code>'deeper'</code>,在第 5 层的数组中包含字符串<code>'deepest'</code>。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>myNestedArray</code>应仅包含数字,布尔值和字符串作为数据元素
|
||||
- text: <code>myNestedArray</code>中的数据元素应当只能是字符串、数字或者布尔值。
|
||||
testString: 'assert.strictEqual((function(arr) { let flattened = (function flatten(arr) { const flat = [].concat(...arr); return flat.some (Array.isArray) ? flatten(flat) : flat; })(arr); for (let i = 0; i < flattened.length; i++) { if ( typeof flattened[i] !== ''number'' && typeof flattened[i] !== ''string'' && typeof flattened[i] !== ''boolean'') { return false } } return true })(myNestedArray), true);'
|
||||
- text: <code>myNestedArray</code>应该有5个级别的深度
|
||||
- text: <code>myNestedArray</code>应该刚好有 5 层数组嵌套。
|
||||
testString: 'assert.strictEqual((function(arr) {let depth = 0;function arrayDepth(array, i, d) { if (Array.isArray(array[i])) { arrayDepth(array[i], 0, d + 1);} else { depth = (d > depth) ? d : depth;}if (i < array.length) { arrayDepth(array, i + 1, d);} }arrayDepth(arr, 0, 0);return depth;})(myNestedArray), 4);'
|
||||
- text: <code>myNestedArray</code>应该在嵌套3级深度的数组中恰好包含一个字符串<code>"deep"</code>
|
||||
- text: <code>myNestedArray</code>里应该有且只有一个字符串<code>"deep"</code>,并且应该出现在第 3 层数组中。
|
||||
testString: assert((function howDeep(array, target, depth = 0) {return array.reduce((combined, current) => {if (Array.isArray(current)) { return combined.concat(howDeep(current, target, depth + 1));} else if (current === target) { return combined.concat(depth);} else { return combined;}}, []);})(myNestedArray, 'deep').length === 1 && (function howDeep(array, target, depth = 0) {return array.reduce((combined, current) => {if (Array.isArray(current)) { return combined.concat(howDeep(current, target, depth + 1));} else if (current === target) { return combined.concat(depth);} else { return combined;}}, []);})(myNestedArray, 'deep')[0] === 2);
|
||||
- text: <code>myNestedArray</code>应该在嵌套4级深度的数组中恰好包含一个字符串<code>"deeper"</code> deep”
|
||||
- text: <code>myNestedArray</code>里应该有且只有一个字符串<code>"deeper"</code>,并且应该出现在第 4 层数组中。
|
||||
testString: assert((function howDeep(array, target, depth = 0) {return array.reduce((combined, current) => {if (Array.isArray(current)) { return combined.concat(howDeep(current, target, depth + 1));} else if (current === target) { return combined.concat(depth);} else { return combined;}}, []);})(myNestedArray, 'deeper').length === 1 && (function howDeep(array, target, depth = 0) {return array.reduce((combined, current) => {if (Array.isArray(current)) { return combined.concat(howDeep(current, target, depth + 1));} else if (current === target) { return combined.concat(depth);} else { return combined;}}, []);})(myNestedArray, 'deeper')[0] === 3);
|
||||
- text: <code>myNestedArray</code>应该在嵌套5级深度的数组中恰好包含一个字符串<code>"deepest"</code> <code>myNestedArray</code> <code>"deepest"</code>
|
||||
- text: <code>myNestedArray</code>里应该有且只有一个字符串<code>"deepest"</code>,并且应该出现在第 5 层数组中。
|
||||
testString: assert((function howDeep(array, target, depth = 0) {return array.reduce((combined, current) => {if (Array.isArray(current)) { return combined.concat(howDeep(current, target, depth + 1));} else if (current === target) { return combined.concat(depth);} else { return combined;}}, []);})(myNestedArray, 'deepest').length === 1 && (function howDeep(array, target, depth = 0) {return array.reduce((combined, current) => {if (Array.isArray(current)) { return combined.concat(howDeep(current, target, depth + 1));} else if (current === target) { return combined.concat(depth);} else { return combined;}}, []);})(myNestedArray, 'deepest')[0] === 4);
|
||||
|
||||
```
|
||||
@ -47,7 +89,6 @@ let myNestedArray = [
|
||||
['iterate', 1.3849, 7, '8.4876', 'arbitrary', 'depth']
|
||||
// change code above this line
|
||||
];
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -60,6 +101,15 @@ let myNestedArray = [
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
let myNestedArray = [
|
||||
// change code below this line
|
||||
['unshift', ['deep', ['deeper', ['deepest']]],false, 1, 2, 3, 'complex', 'nested'],
|
||||
['loop', 'shift', 6, 7, 1000, 'method'],
|
||||
['concat', false, true, 'spread', 'array'],
|
||||
['mutate', 1327.98, 'splice', 'slice', 'push'],
|
||||
['iterate', 1.3849, 7, '8.4876', 'arbitrary', 'depth']
|
||||
// change code above this line
|
||||
];
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,24 +2,28 @@
|
||||
id: 587d7b7d367417b2b2512b1e
|
||||
title: Generate an Array of All Object Keys with Object.keys()
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用Object.keys()生成所有对象键的数组
|
||||
forumTopicId: 301160
|
||||
localeTitle: 使用 Object.Keys() 生成对象所有键组成的数组
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">我们还可以使用<code>Object.keys()</code>方法生成一个数组,其中包含存储在对象中的所有键,并传入一个对象作为参数。这将返回一个数组,其中的字符串表示对象中的每个属性。同样,数组中的条目没有特定的顺序。 </section>
|
||||
<section id='description'>
|
||||
我们还可以输入一个对象作为参数来调用<code>Object.keys()</code>方法,使其生成一个包含对象中所有键的数组。这会返回一个由对象中所有键的名称(字符串)组成的数组。再次说明,这个数组中的项的顺序是不确定的。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">完成编写<code>getArrayOfUsers</code>函数,以便它返回一个数组,该数组包含它作为参数接收的对象中的所有属性。 </section>
|
||||
<section id='instructions'>
|
||||
请你完成<code>getArrayOfUsers</code>函数,使其返回一个包含输入的对象的所有属性的数组。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>users</code>对象仅包含<code>Alan</code> , <code>Jeff</code> , <code>Sarah</code>和<code>Ryan</code>
|
||||
- text: <code>users</code>对象应该只包含<code>Alan</code>、<code>Jeff</code>、<code>Sarah</code>和<code>Ryan</code>这 4 个键
|
||||
testString: assert('Alan' in users && 'Jeff' in users && 'Sarah' in users && 'Ryan' in users && Object.keys(users).length === 4);
|
||||
- text: <code>getArrayOfUsers</code>函数返回一个数组,其中包含<code>users</code>对象中的所有键
|
||||
- text: <code>getArrayOfUsers</code>函数应该返回一个包含<code>users</code>对象中所有键的数组
|
||||
testString: assert((function() { users.Sam = {}; users.Lewis = {}; let R = getArrayOfUsers(users); return (R.indexOf('Alan') !== -1 && R.indexOf('Jeff') !== -1 && R.indexOf('Sarah') !== -1 && R.indexOf('Ryan') !== -1 && R.indexOf('Sam') !== -1 && R.indexOf('Lewis') !== -1); })() === true);
|
||||
|
||||
```
|
||||
@ -58,7 +62,6 @@ function getArrayOfUsers(obj) {
|
||||
}
|
||||
|
||||
console.log(getArrayOfUsers(users));
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -71,6 +74,30 @@ console.log(getArrayOfUsers(users));
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
let users = {
|
||||
Alan: {
|
||||
age: 27,
|
||||
online: false
|
||||
},
|
||||
Jeff: {
|
||||
age: 32,
|
||||
online: true
|
||||
},
|
||||
Sarah: {
|
||||
age: 48,
|
||||
online: false
|
||||
},
|
||||
Ryan: {
|
||||
age: 19,
|
||||
online: true
|
||||
}
|
||||
};
|
||||
|
||||
function getArrayOfUsers(obj) {
|
||||
return Object.keys(obj);
|
||||
}
|
||||
|
||||
console.log(getArrayOfUsers(users));
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,15 +2,37 @@
|
||||
id: 587d7b7b367417b2b2512b15
|
||||
title: Iterate Through All an Array's Items Using For Loops
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用for循环遍历所有数组的项目
|
||||
forumTopicId: 301161
|
||||
localeTitle: 使用 For 循环迭代数组的所有项
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">有时在使用数组时,能够遍历每个项目以查找我们可能需要的一个或多个元素,或者根据哪些数据项符合某组标准来操作数组非常方便。 JavaScript提供了几种内置方法,每种方法都以稍微不同的方式迭代数组以实现不同的结果(例如<code>every()</code> , <code>forEach()</code> , <code>map()</code>等),但是这种技术最灵活并且为我们提供了最大的控制量是一个简单的<code>for</code>循环。考虑以下: <blockquote> function greaterThanTen(arr){ <br>让newArr = []; <br> for(let i = 0; i <arr.length; i ++){ <br> if(arr [i]> 10){ <br> (ARR [I])newArr.push; <br> } <br> } <br>返回newArr; <br> } <br><br> greaterThanTen([2,12,8,14,80,0,1]); <br> //返回[12,14,80] </blockquote>使用<code>for</code>循环,此函数遍历并访问数组的每个元素,并使其经受我们创建的简单测试。通过这种方式,我们可以轻松地以编程方式确定哪些数据项大于<code>10</code> ,并返回包含这些项的新数组。 </section>
|
||||
<section id='description'>
|
||||
在进行与数组有关的编程时,我们有时需要遍历数组的所有元素来找出我们需要的元素,或者对数组执行特定的操作。JavaScript 提供了几个内置的方法,它们以不同的方式遍历数组来获得不同的结果(如<code>every()</code>、<code>forEach()</code>、<code>map()</code>等等)。而简单的<code>for</code>循环不仅能实现这些功能,而且相比之下也更灵活。
|
||||
请看以下例子:
|
||||
|
||||
```js
|
||||
function greaterThanTen(arr) {
|
||||
let newArr = [];
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i] > 10) {
|
||||
newArr.push(arr[i]);
|
||||
}
|
||||
}
|
||||
return newArr;
|
||||
}
|
||||
|
||||
greaterThanTen([2, 12, 8, 14, 80, 0, 1]);
|
||||
// 返回 [12, 14, 80]
|
||||
```
|
||||
|
||||
这个函数使用一个<code>for</code>循环来遍历一个数组,逐一对其中的元素进行测试。我们用这个方法简单地以编程的方式找出了数组中大于<code>10</code>的元素,并返回了一个包含这些元素的数组。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">我们定义了一个函数<code>filteredArray</code> ,它接受<code>arr</code> ,一个嵌套数组和<code>elem</code>作为参数,并返回一个新数组。 <code>elem</code>表示在<code>arr</code>嵌套的一个或多个数组上可能存在或不存在的元素。使用<code>for</code>循环修改函数,以返回已传递数组的过滤版本,以便删除嵌套在包含<code>elem</code> <code>arr</code>中的任何数组。 </section>
|
||||
<section id='instructions'>
|
||||
我们已经定义了一个<code>filteredArray</code>函数,它接受一个嵌套的数组参数<code>arr</code>以及一个<code>elem</code>参数,并要返回一个新数组。<code>arr</code>数组中的数组可能包含<code>elem</code>元素,也可能不包含。请修改该函数,用一个<code>for</code>循环来做筛选,使函数返回一个由<code>arr</code>中不包含<code>elem</code>的数组组成的新数组。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
@ -48,7 +70,6 @@ function filteredArray(arr, elem) {
|
||||
|
||||
// change code here to test different cases:
|
||||
console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -61,6 +82,17 @@ console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
function filteredArray(arr, elem) {
|
||||
let newArr = [];
|
||||
// change code below this line
|
||||
for (let i = 0; i<arr.length; i++) {
|
||||
if (arr[i].indexOf(elem) < 0) {
|
||||
newArr.push(arr[i]);
|
||||
}
|
||||
}
|
||||
// change code above this line
|
||||
return newArr;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,26 +2,66 @@
|
||||
id: 587d7b7d367417b2b2512b1d
|
||||
title: 'Iterate Through the Keys of an Object with a for...in Statement'
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用for ... in Statement中的对象键迭代
|
||||
forumTopicId: 301162
|
||||
localeTitle: '使用 for...in 语句迭代对象'
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">有时您可能需要遍历对象中的所有键。这需要JavaScript中的特定语法,称为<dfn>for ... in</dfn>语句。对于我们的<code>users</code>对象,这可能看起来像: <blockquote> for(让用户在用户中){ <br>的console.log(用户); <br> }; <br><br> //日志: <br>艾伦<br>杰夫<br>莎拉<br>瑞安</blockquote>在这个语句中,我们定义了一个变量<code>user</code> ,正如您所看到的,在每次迭代期间,当该语句循环遍历该对象时,该变量被重置为每个对象的键,从而导致每个用户的名称被打印到控制台。 <strong>注意:</strong> <br>对象不像数组那样保持对存储键的排序;因此,当引用或访问该密钥时,对象上的键位置或其出现的相对顺序是无关紧要的。 </section>
|
||||
<section id='description'>
|
||||
|
||||
有时候你需要遍历一个对象中的所有键。这需要 JavaScript 中的一个特殊语法:<dfn>for...in</dfn> 语句。以遍历 <code>users</code> 对象的键为例:
|
||||
|
||||
```js
|
||||
for (let user in users) {
|
||||
console.log(user);
|
||||
}
|
||||
|
||||
// logs:
|
||||
Alan
|
||||
Jeff
|
||||
Sarah
|
||||
Ryan
|
||||
```
|
||||
|
||||
在这个语句中,我们定义了一个<code>user</code>变量,你可以看到,这个变量在 for...in 语句对对象的每一个键的遍历中都会被重置。
|
||||
<strong>注意:</strong><br>跟数组不同,对象中的键是无序的,因此一个对象中某个键的位置,或者说它出现的相对顺序,在引用或访问该键时是不确定的。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">我们定义了一个函数<code>countOnline</code> ;在此函数中使用<dfn>for ... in</dfn>语句循环访问<code>users</code>对象中的<code>users</code>并返回其<code>online</code>属性设置为<code>true</code>的用户数。 </section>
|
||||
<section id='instructions'>
|
||||
|
||||
我们已经定义了一个<code>countOnline</code>函数,请在其中使用一个 <dfn>for...in</dfn> 语句来遍历<code>users</code>对象中的用户,并返回<code>online</code>属性为<code>true</code>的用户的数量。
|
||||
|
||||
|
||||
```js
|
||||
{
|
||||
Alan: {
|
||||
online: false
|
||||
},
|
||||
Jeff: {
|
||||
online: true
|
||||
},
|
||||
Sarah: {
|
||||
online: false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>users</code>对象包含用户<code>Jeff</code>和<code>Ryan</code> , <code>online</code>设置为<code>true</code> ,用户<code>Alan</code>和<code>Sarah</code> <code>online</code>设置为<code>false</code>
|
||||
testString: 'assert(users.Alan.online === false && users.Jeff.online === true && users.Sarah.online === false && users.Ryan.online === true, "The <code>users</code> object contains users <code>Jeff</code> and <code>Ryan</code> with <code>online</code> set to <code>true</code> and users <code>Alan</code> and <code>Sarah</code> with <code>online</code> set to <code>false</code>");'
|
||||
- text: 函数<code>countOnline</code>返回<code>online</code>属性设置为<code>true</code>的用户数
|
||||
testString: 'assert((function() { users.Harry = {online: true}; users.Sam = {online: true}; users.Carl = {online: true}; return countOnline(users) })() === 5, "The function <code>countOnline</code> returns the number of users with the <code>online</code> property set to <code>true</code>");'
|
||||
|
||||
- text: 函数 <code>countOnline</code> 应该使用 `for in` 语句遍历传入对象的key。
|
||||
testString: assert(code.match(/for\s*\(\s*(var|let)\s+[a-zA-Z_$]\w*\s+in\s+[a-zA-Z_$]\w*\s*\)\s*{/));
|
||||
- text: '当传入 <code>{ Alan: { online: false }, Jeff: { online: true }, Sarah: { online: false } }</code> 时,函数 <code>countOnline</code> 应该返回 <code>1</code>。'
|
||||
testString: assert(countOnline(usersObj1) === 1);
|
||||
- text: '当传入 <code>{ Alan: { online: true }, Jeff: { online: false }, Sarah: { online: true } }</code> 时,函数 <code>countOnline</code> 应该返回 <code>2</code>。'
|
||||
testString: assert(countOnline(usersObj2) === 2);
|
||||
- text: '当传入 <code>{ Alan: { online: false }, Jeff: { online: false }, Sarah: { online: false } }</code> 时,函数 <code>countOnline</code> 应该返回 <code>0</code>。'
|
||||
testString: assert(countOnline(usersObj3) === 0);
|
||||
```
|
||||
|
||||
</section>
|
||||
@ -32,37 +72,58 @@ tests:
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
let users = {
|
||||
Alan: {
|
||||
age: 27,
|
||||
online: false
|
||||
},
|
||||
Jeff: {
|
||||
age: 32,
|
||||
online: true
|
||||
},
|
||||
Sarah: {
|
||||
age: 48,
|
||||
online: false
|
||||
},
|
||||
Ryan: {
|
||||
age: 19,
|
||||
online: true
|
||||
}
|
||||
};
|
||||
|
||||
function countOnline(obj) {
|
||||
function countOnline(usersObj) {
|
||||
// change code below this line
|
||||
|
||||
// change code above this line
|
||||
}
|
||||
|
||||
console.log(countOnline(users));
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
const usersObj1 = {
|
||||
Alan: {
|
||||
online: false
|
||||
},
|
||||
Jeff: {
|
||||
online: true
|
||||
},
|
||||
Sarah: {
|
||||
online: false
|
||||
}
|
||||
}
|
||||
|
||||
const usersObj2 = {
|
||||
Alan: {
|
||||
online: true
|
||||
},
|
||||
Jeff: {
|
||||
online: false
|
||||
},
|
||||
Sarah: {
|
||||
online: true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const usersObj3 = {
|
||||
Alan: {
|
||||
online: false
|
||||
},
|
||||
Jeff: {
|
||||
online: false
|
||||
},
|
||||
Sarah: {
|
||||
online: false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
@ -71,6 +132,17 @@ console.log(countOnline(users));
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
|
||||
function countOnline(usersObj) {
|
||||
let online = 0;
|
||||
for(let user in usersObj){
|
||||
if(usersObj[user].online) {
|
||||
online++;
|
||||
}
|
||||
}
|
||||
return online;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,26 +2,30 @@
|
||||
id: 587d7b7d367417b2b2512b1f
|
||||
title: Modify an Array Stored in an Object
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301163
|
||||
localeTitle: 修改存储在对象中的数组
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">现在您已经看到了JavaScript对象的所有基本操作。您可以添加,修改和删除键值对,检查键是否存在,并迭代对象中的所有键。随着您继续学习JavaScript,您将看到更多功能的对象应用程序。此外,课程后面的可选高级数据结构课程还涵盖ES6 <dfn>Map</dfn>和<dfn>Set</dfn>对象,这两个对象与普通对象类似,但提供了一些附加功能。既然您已经学习了数组和对象的基础知识,那么您已经准备好开始使用JavaScript解决更复杂的问题了! </section>
|
||||
<section id='description'>
|
||||
现在你已经接触到 JavaScript 对象的所有运算。你可以增加、修改和移除键值对,检查某个键是否存在,并且遍历一个对象中的所有键。在你继续学习 JavaScript 的过程中,你会看到对象的更多用法。另外,后续的《高级数据结构》课程还会介绍 ES6 的 <dfn>Map</dfn> 和 <dfn>Set</dfn> 对象。这两种对象都跟一般的对象相似,但它们提供了一些额外的特性。现在你已经学到了数组和对象的基础知识,你已经可以继续用 JavaScript 来解决更加复杂的问题了!
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">看看我们在代码编辑器中提供的对象。 <code>user</code>对象包含三个键。 <code>data</code>键包含五个键,其中一个键包含一组<code>friends</code> 。从这里,您可以看到灵活的对象如何作为数据结构。我们已经开始编写一个函数<code>addFriend</code> 。完成编写它以便它获取<code>user</code>对象并将<code>friend</code>参数的名称添加到存储在<code>user.data.friends</code>中的数组并返回该数组。 </section>
|
||||
<section id='instructions'>
|
||||
请你看一下代码编辑器中我们提供的对象。<code>user</code>对象包含 3 个键。<code>data</code>对象包含 5 个键,其中一个包含一个<code>friends</code>数组。从这个例子你可以看到对象作为数据结构是多么的灵活。我们已经写了<code>addFriend</code>函数的一部分,请你完成这个函数,使其接受一个<code>user</code>对象,将<code>friend</code>参数中的名字添加到<code>user.data.friends</code>数组中并返回该数组。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>user</code>对象具有<code>name</code> , <code>age</code>和<code>data</code>键
|
||||
- text: <code>user</code>对象应该包含<code>name</code>、<code>age</code>和<code>data</code>三个键。
|
||||
testString: assert('name' in user && 'age' in user && 'data' in user);
|
||||
- text: <code>addFriend</code>函数接受<code>user</code>对象和<code>friend</code>字符串作为参数,并将朋友添加到<code>user</code>对象中的<code>friends</code>数组
|
||||
- text: <code>addFriend</code>函数应该接受一个<code>user</code>对象和一个<code>friend</code>字符串作为输入参数,并将 friend 插入到<code>user</code>对象的<code>friends</code>数组中。
|
||||
testString: assert((function() { let L1 = user.data.friends.length; addFriend(user, 'Sean'); let L2 = user.data.friends.length; return (L2 === L1 + 1); })());
|
||||
- text: '<code>addFriend(user, "Pete")</code>应该返回<code>["Sam", "Kira", "Tomo", "Pete"]</code>'
|
||||
- text: '<code>addFriend(user, "Pete")</code>应该返回<code>["Sam", "Kira", "Tomo", "Pete"]</code>。"
|
||||
testString: assert.deepEqual((function() { delete user.data.friends; user.data.friends = ['Sam', 'Kira', 'Tomo']; return addFriend(user, 'Pete') })(), ['Sam', 'Kira', 'Tomo', 'Pete']);
|
||||
|
||||
```
|
||||
@ -61,7 +65,6 @@ function addFriend(userObj, friend) {
|
||||
}
|
||||
|
||||
console.log(addFriend(user, 'Pete'));
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -74,6 +77,30 @@ console.log(addFriend(user, 'Pete'));
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
let user = {
|
||||
name: 'Kenneth',
|
||||
age: 28,
|
||||
data: {
|
||||
username: 'kennethCodesAllDay',
|
||||
joinDate: 'March 26, 2016',
|
||||
organization: 'freeCodeCamp',
|
||||
friends: [
|
||||
'Sam',
|
||||
'Kira',
|
||||
'Tomo'
|
||||
],
|
||||
location: {
|
||||
city: 'San Francisco',
|
||||
state: 'CA',
|
||||
country: 'USA'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function addFriend(userObj, friend) {
|
||||
userObj.data.friends.push(friend);
|
||||
return userObj.data.friends;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,28 +2,49 @@
|
||||
id: 587d7b7c367417b2b2512b19
|
||||
title: Modify an Object Nested Within an Object
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301164
|
||||
localeTitle: 修改嵌套在对象中的对象
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">现在让我们来看一个稍微复杂的对象。对象属性可以嵌套到任意深度,它们的值可以是JavaScript支持的任何类型的数据,包括数组甚至其他对象。考虑以下: <blockquote>让nestedObject = { <br> id:28802695164, <br>日期:'2016年12月31日', <br>数据:{ <br>总用户:99, <br>在线:80, <br> onlineStatus:{ <br>活跃:67, <br>离开:13 <br> } <br> } <br> }; </blockquote> <code>nestedObject</code>有三个唯一的键: <code>id</code> ,其值为数字, <code>date</code>为字符串的<code>data</code> , <code>data</code> ,其值为另一个嵌套在其中的对象。虽然结构很快就会变得复杂,但我们仍然可以使用相同的符号来访问我们需要的信息。 </section>
|
||||
<section id='description'>
|
||||
现在我们来看一个稍微复杂一点的对象。对象中也可以嵌套任意层的对象。对象的属性值可以是 JavaScript 支持的任意类型,包括数组和其他对象。请看以下例子:
|
||||
|
||||
```js
|
||||
let nestedObject = {
|
||||
id: 28802695164,
|
||||
date: 'December 31, 2016',
|
||||
data: {
|
||||
totalUsers: 99,
|
||||
online: 80,
|
||||
onlineStatus: {
|
||||
active: 67,
|
||||
away: 13
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
<code>nestedObject</code>有 3 个唯一的键:值为一个数字的<code>id</code>、值为一个字符串的<code>date</code>和值为一个嵌套了其他对象的对象的<code>data</code>。虽然对象中的数据可能很复杂,我们仍能使用上一个挑战中讲的符号来访问我们需要的信息。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">在这里,我们定义了一个对象<code>userActivity</code> ,其中包含嵌套在其中的另一个对象。您可以像修改上一个挑战中的属性一样修改此嵌套对象的属性。将<code>online</code>密钥的值设置为<code>45</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
我们已经定义了一个<code>userActivity</code>对象,它包含了另一个对象。你可以用上一个挑战中那样的方式来修改被嵌套的对象的属性。请将<code>online</code>属性设为<code>45</code>。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>userActivity</code>具有<code>id</code> , <code>date</code>和<code>data</code>属性
|
||||
- text: <code>userActivity</code>应该含有<code>id</code>、<code>date</code>和<code>data</code>属性。
|
||||
testString: assert('id' in userActivity && 'date' in userActivity && 'data' in userActivity);
|
||||
- text: <code>userActivity</code>具有设置为具有密钥<code>totalUsers</code>和<code>online</code>的对象的<code>data</code>密钥
|
||||
- text: <code>userActivity</code>应该有一个<code>data</code>属性,该属性要是一个含有<code>totalUsers</code>和<code>online</code>属性的对象。
|
||||
testString: assert('totalUsers' in userActivity.data && 'online' in userActivity.data);
|
||||
- text: 嵌套在<code>userActivity</code> <code>data</code>键中的<code>online</code>属性应设置为<code>45</code>
|
||||
- text: <code>userActivity</code>的<code>data</code>属性值中的<code>online</code>属性应该被设为<code>45</code>。
|
||||
testString: assert(userActivity.data.online === 45);
|
||||
- text: <code>online</code>属性使用点或括号表示法设置
|
||||
- text: 你应该用点符号或者方括号符号来设置<code>online</code>属性。
|
||||
testString: 'assert.strictEqual(code.search(/online: 45/), -1);'
|
||||
|
||||
```
|
||||
@ -50,7 +71,6 @@ let userActivity = {
|
||||
// change code above this line
|
||||
|
||||
console.log(userActivity);
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -63,6 +83,16 @@ console.log(userActivity);
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
let userActivity = {
|
||||
id: 23894201352,
|
||||
date: 'January 1, 2017',
|
||||
data: {
|
||||
totalUsers: 51,
|
||||
online: 42
|
||||
}
|
||||
};
|
||||
|
||||
userActivity.data.online = 45;
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,15 +2,39 @@
|
||||
id: 587d78b2367417b2b2512b0f
|
||||
title: Remove Items from an Array with pop() and shift()
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用pop()和shift()从数组中删除项
|
||||
forumTopicId: 301165
|
||||
localeTitle: 使用 pop() 和 shift() 从数组中删除项目
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description"> <code>push()</code>和<code>unshift()</code>都有相应的几乎相反的方法: <code>pop()</code>和<code>shift()</code> 。正如您现在可能已经猜到的那样, <code>pop()</code>不是添加,而是从数组的末尾<em>删除</em>元素,而<code>shift()</code>从头开始删除元素。 <code>pop()</code>和<code>shift()</code>及其兄弟<code>push()</code>和<code>unshift()</code>之间的关键区别在于,两个方法都不接受参数,并且每个方法只允许一次由单个元素修改数组。让我们来看看: <blockquote>让问候= ['什么事情?','你好','看到你!']; <br><br> greetings.pop(); <br> //现在等于['whats up?','hello'] <br><br> greetings.shift(); <br> //现在等于['你好'] </blockquote>我们还可以使用以下任一方法返回已删除元素的值: <blockquote> let popped = greetings.pop(); <br> //返回'你好' <br> //问候现在等于[] </blockquote></section>
|
||||
<section id='description'>
|
||||
<code>push()</code>和<code>unshift()</code>都分别有一个作用基本与之相反的函数:<code>pop()</code>和<code>shift()</code>。你现在或许已经猜到,与插入元素相反,<code>pop()</code>从数组的末尾<em>移除</em>一个元素,而<code>shift()</code>从数组的开头移除一个元素。<code>pop()</code>和<code>shift()</code>与对应的<code>push()</code>和<code>unshift()</code>的关键区别在于,前者不能接受输入参数,而且每次只能修改数组中的一个元素。
|
||||
让我们来看以下的例子:
|
||||
|
||||
```js
|
||||
let greetings = ['whats up?', 'hello', 'see ya!'];
|
||||
|
||||
greetings.pop();
|
||||
// now equals ['whats up?', 'hello']
|
||||
|
||||
greetings.shift();
|
||||
// now equals ['hello']
|
||||
```
|
||||
|
||||
还可以用这些方法返回移除的元素,像这样:
|
||||
|
||||
```js
|
||||
let popped = greetings.pop();
|
||||
// returns 'hello'
|
||||
// greetings now equals []
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">我们定义了一个函数<code>popShift</code> ,它将一个数组作为参数并返回一个新数组。使用<code>pop()</code>和<code>shift()</code>修改函数,删除参数数组的第一个和最后一个元素,并将删除的元素分配给它们对应的变量,以便返回的数组包含它们的值。 </section>
|
||||
<section id='instructions'>
|
||||
我们已经定义了一个<code>popShift</code>函数,它会接收一个数组作为输入参数并返回一个新的数组。请你修改这个函数,使用<code>pop()</code>和<code>shift()</code>来移除输入的数组的第一个元素和最后一个元素,并将这两个被移除的元素赋值给对应的变量,使得返回的数组包含它们的值。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
@ -42,7 +66,6 @@ function popShift(arr) {
|
||||
|
||||
// do not change code below this line
|
||||
console.log(popShift(['challenge', 'is', 'not', 'complete']));
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -55,6 +78,11 @@ console.log(popShift(['challenge', 'is', 'not', 'complete']));
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
function popShift(arr) {
|
||||
let popped = arr.pop(); // change this line
|
||||
let shifted = arr.shift(); // change this line
|
||||
return [shifted, popped];
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,26 +2,54 @@
|
||||
id: 587d78b2367417b2b2512b10
|
||||
title: Remove Items Using splice()
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用splice()删除项目
|
||||
forumTopicId: 301166
|
||||
localeTitle: 使用 splice() 删除项目
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">好的,所以我们已经学会了如何使用<code>shift()</code>和<code>pop()</code>从数组的开头和结尾删除元素,但是如果我们想要从中间某处删除元素呢?或者一次删除多个元素?好吧,这就是<code>splice()</code>用武之地<code>splice()</code>允许我们这样做:从数组中的任何位置<strong>删除任意数量的连续元素</strong> 。 <code>splice()</code>可能需要长达3个参数,但现在,我们将重点放在刚第一2.第2个参数<code>splice()</code>是其代表索引的整数,或位置中,阵列的该<code>splice()</code>是为呼吁。请记住,数组是<em>零索引的</em> ,所以为了表示数组的第一个元素,我们将使用<code>0</code> 。 <code>splice()</code>的第一个参数表示从中开始删除元素的数组的索引,而第二个参数表示要删除的元素的数量。例如: <blockquote>让array = ['今天','是','不','所以','伟大']; <br><br> array.splice(2,2); <br> //删除以第3个元素开头的2个元素<br> //数组现在等于['今天','是','很棒'] </blockquote> <code>splice()</code>不仅修改了它被调用的数组,而且还返回一个包含被删除元素值的新数组: <blockquote>让array = ['我','我','感觉','真的','快乐']; <br><br> let newArray = array.splice(3,2); <br> // newArray等于['真'','快乐'] </blockquote></section>
|
||||
<section id='description'>
|
||||
在上面的挑战中,我们已经学到了如何利用<code>shift()</code>和<code>pop()</code>从数组的开头或者末尾移除元素,但如果我们想移除数组中间的一个元素呢?或者想一次移除多个元素呢?这时候我们就需要<code>splice()</code>了。<code>splice()</code>让我们可以从数组中的任意位置<strong>移除任意数量的连续的元素</strong>。
|
||||
<code>splice()</code>最多可以接受 3 个参数,但现在我们先关注前两个。<code>splice()</code>接收的前两个参数基于调用<code>splice()</code>数组中元素的索引。记住,数组的索引是<em>从 0 开始的</em>(<em>zero-indexed</em>),所以我们要用<code>0</code>来指示数组中的第一个元素。<code>splice()</code>的第一个参数代表从数组中的哪个索引开始移除元素,而第二个参数指示要从数组中删除多少个元素。例如:
|
||||
|
||||
```js
|
||||
let array = ['today', 'was', 'not', 'so', 'great'];
|
||||
|
||||
array.splice(2, 2);
|
||||
// 从第三个索引位置开始移除 2 个元素
|
||||
// array 现在是 ['today', 'was', 'great']
|
||||
```
|
||||
|
||||
<code>splice()</code>不仅从被调用的数组中移除元素,还会返回一个包含被移除元素的数组:
|
||||
|
||||
```js
|
||||
let array = ['I', 'am', 'feeling', 'really', 'happy'];
|
||||
|
||||
let newArray = array.splice(3, 2);
|
||||
// newArray 是 ['really', 'happy']
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">我们定义了一个函数<code>sumOfTen</code> ,它将一个数组作为参数,并返回该数组元素的总和。使用<code>splice()</code>修改函数,使其返回值<code>10</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
|
||||
给定初始化的数组 `arr`。使用 `splice()` 从 `arr` 里移除元素,使剩余的元素的和为 <code>10</code>。
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>sumOfTen</code>应该返回10
|
||||
testString: 'assert.strictEqual(sumOfTen([2, 5, 1, 5, 2, 1]), 10, "<code>sumOfTen</code> should return 10");'
|
||||
- text: <code>sumOfTen</code>函数应该使用<code>splice()</code>方法
|
||||
testString: 'assert.notStrictEqual(sumOfTen.toString().search(/\.splice\(/), -1, "The <code>sumOfTen</code> function should utilize the <code>splice()</code> method");'
|
||||
|
||||
- text: 不应该修改这一行 <code>const arr = [2, 4, 5, 1, 7, 5, 2, 1];</code>。
|
||||
testString: assert(code.replace(/\s/g, '').match(/constarr=\[2,4,5,1,7,5,2,1\];?/));
|
||||
- text: <code>arr</code> 的剩余元素和应该为 <code>10</code>。
|
||||
testString: assert.strictEqual(arr.reduce((a, b) => a + b), 10);
|
||||
- text: 应该利用 <code>arr</code> 的 <code>splice()</code>。
|
||||
testString: assert(code.replace(/\s/g, '').match(/arr\.splice\(/));
|
||||
- text: splice 应该只删除 <code>arr</code> 里面的元素,不能给 <code>arr</code> 添加元素。
|
||||
testString: assert(!code.replace(/\s/g, '').match(/arr\.splice\(\d+,\d+,\d+.*\)/g));
|
||||
```
|
||||
|
||||
</section>
|
||||
@ -32,16 +60,11 @@ tests:
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function sumOfTen(arr) {
|
||||
// change code below this line
|
||||
|
||||
// change code above this line
|
||||
return arr.reduce((a, b) => a + b);
|
||||
}
|
||||
|
||||
// do not change code below this line
|
||||
console.log(sumOfTen([2, 5, 1, 5, 2, 1]));
|
||||
const arr = [2, 4, 5, 1, 7, 5, 2, 1];
|
||||
// only change code below this line
|
||||
|
||||
// only change code above this line
|
||||
console.log(arr);
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -54,6 +77,8 @@ console.log(sumOfTen([2, 5, 1, 5, 2, 1]));
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
const arr = [2, 4, 5, 1, 7, 5, 2, 1];
|
||||
arr.splice(1, 4);
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,30 +2,69 @@
|
||||
id: 587d7b7e367417b2b2512b20
|
||||
title: Use an Array to Store a Collection of Data
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301167
|
||||
localeTitle: 使用数组存储数据集合
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">以下是阵列数据结构最简单实现的示例。这被称为<dfn>一维数组</dfn> ,意味着它只有一个级别,或者它没有嵌套在其中的任何其他数组。请注意,它包含<dfn>布尔值</dfn> , <dfn>字符串</dfn>和<dfn>数字</dfn> ,以及其他有效的JavaScript数据类型: <blockquote> let simpleArray = ['one',2,'three',true,false,undefined,null]; <br>的console.log(simpleArray.length); <br> //记录7 </blockquote>所有数组都有一个length属性,如上所示,可以使用语法<code>Array.length</code>轻松访问<code>Array.length</code> 。下面可以看到更复杂的数组实现。这称为<dfn>多维数组</dfn> ,或包含其他数组的数组。请注意,此数组还包含JavaScript <dfn>对象</dfn> ,我们将在下一节中详细介绍,但是现在,您需要知道的是,数组也能够存储复杂对象。 <blockquote>让complexArray = [ <br> [ <br> { <br>一:1, <br>二:2 <br> }, <br> { <br>三:3, <br>四:4 <br> } <br> ] <br> [ <br> { <br> a:“a”, <br> b:“b” <br> }, <br> { <br> c:“c”, <br> d:“d” <br> } <br> ] <br> ]。 </blockquote></section>
|
||||
<section id='description'>
|
||||
以下是<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
|
||||
```
|
||||
|
||||
可以在上述例子中看到,所有数组都有一个<dfn>长度(length)</dfn>属性。可以简单地使用<code>Array.length</code>方法来访问它。
|
||||
下面是一个关于数组的更复杂的例子。这是一个<dfn>多维数组(multi-dimensional Array</dfn>),或者说是一个包含了其他数组的数组。可以注意到,在它的内部还包含了 JavaScript 中的<dfn>对象(objects)</dfn>结构。我们会在后面的小节中讨论该数据结构,但现在你只需要知道数组能够存储复杂的对象类型数据。
|
||||
|
||||
```js
|
||||
let complexArray = [
|
||||
[
|
||||
{
|
||||
one: 1,
|
||||
two: 2
|
||||
},
|
||||
{
|
||||
three: 3,
|
||||
four: 4
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
a: "a",
|
||||
b: "b"
|
||||
},
|
||||
{
|
||||
c: "c",
|
||||
d: "d"
|
||||
}
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">我们定义了一个名为<code>yourArray</code>的变量。通过为<code>yourArray</code>变量指定长度至少为5个元素的数组来完成该语句。您的数组应至少包含一个<dfn>字符串</dfn> ,一个<dfn>数字</dfn>和一个<dfn>布尔值</dfn> 。 </section>
|
||||
<section id='instructions'>
|
||||
我们已经定义了一个名为<code>yourArray</code>的变量。请修改题目中的语句,将一个含有至少 5 个元素的数组赋值给<code>yourArray</code>变量。你的数组应该包含至少一个 <dfn>string</dfn> 类型的数据、一个 <dfn>number</dfn> 类型的数据和一个 <dfn>boolean</dfn> 类型的数据。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: yourArray是一个数组
|
||||
- text: yourArray 应该是一个数组。
|
||||
testString: assert.strictEqual(Array.isArray(yourArray), true);
|
||||
- text: <code>yourArray</code>至少有5个元素
|
||||
- text: <code>yourArray</code>至少要包含 5 个元素。
|
||||
testString: assert.isAtLeast(yourArray.length, 5);
|
||||
- text: <code>yourArray</code>至少包含一个<code>boolean</code>
|
||||
- text: <code>yourArray</code>应该包含至少一个<code>boolean</code>。
|
||||
testString: assert(yourArray.filter( el => typeof el === 'boolean').length >= 1);
|
||||
- text: <code>yourArray</code>至少包含一个<code>number</code>
|
||||
- text: <code>yourArray</code>应该包含至少一个<code>number</code>。
|
||||
testString: assert(yourArray.filter( el => typeof el === 'number').length >= 1);
|
||||
- text: <code>yourArray</code>至少包含一个<code>string</code>
|
||||
- text: <code>yourArray</code>应该包含至少一个<code>string</code>。
|
||||
testString: assert(yourArray.filter( el => typeof el === 'string').length >= 1);
|
||||
|
||||
```
|
||||
@ -39,7 +78,6 @@ tests:
|
||||
|
||||
```js
|
||||
let yourArray; // change this line
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -52,6 +90,7 @@ let yourArray; // change this line
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
let yourArray = ['a string', 100, true, ['one', 2], 'another string'];
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,24 +2,35 @@
|
||||
id: 587d7b7c367417b2b2512b1b
|
||||
title: Use the delete Keyword to Remove Object Properties
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用删除关键字删除对象属性
|
||||
forumTopicId: 301168
|
||||
localeTitle: 使用 delete 关键字删除对象属性
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">现在你知道了什么是对象及其基本特征和优点。简而言之,它们是键值存储,它提供了一种灵活,直观的数据结构方式, <strong><em>并且</em></strong>它们提供了非常快速的查找时间。在其余的挑战中,我们将描述您可以对对象执行的几个常见操作,以便您可以轻松地在程序中应用这些有用的数据结构。在早期的挑战中,我们都添加并修改了对象的键值对。在这里,我们将看到如何从对象中<em>删除</em>键值对。让我们最后一次重新审视我们的<code>foods</code>对象示例。如果我们想删除<code>apples</code>键,我们可以使用<code>delete</code>关键字删除它,如下所示: <blockquote>删除foods.apples; </blockquote></section>
|
||||
<section id='description'>
|
||||
现在你已经知道什么是对象以及对象的基本特性和用途。总之,对象是以键值对的形式,灵活、直观地存储结构化数据的一种方式,<strong><em>并且</em></strong>查找对象属性的速度是很快的。在本章剩下的挑战中,我们会讲对象的几种常用操作,这样你能更好地在你的程序中使用这种有用的数据结构。
|
||||
在之前的挑战中,我们已经试过新增和修改对象中的键值对。现在我们来看如何从一个对象中<em>移除</em>一个键值对。
|
||||
我们再来看上一个挑战中的<code>foods</code>对象。如果我们想移除<code>apples</code>属性,我们可以使用<code>delete</code>关键字:
|
||||
|
||||
```js
|
||||
delete foods.apples;
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">使用delete关键字从<code>foods</code>对象中删除<code>oranges</code> , <code>plums</code>和<code>strawberries</code>键。 </section>
|
||||
<section id='instructions'>
|
||||
请你用 delete 关键字来移除<code>foods</code>中的<code>oranges</code>、<code>plums</code>和<code>strawberries</code>属性。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>foods</code>对象只有三个键: <code>apples</code> , <code>grapes</code>和<code>bananas</code>
|
||||
- text: <code>foods</code>对象应该只含有 3 个键:<code>apples</code>、<code>grapes</code>和<code>bananas</code>。
|
||||
testString: 'assert(!foods.hasOwnProperty(''oranges'') && !foods.hasOwnProperty(''plums'') && !foods.hasOwnProperty(''strawberries'') && Object.keys(foods).length === 3);'
|
||||
- text: 使用<code>delete</code> <code>oranges</code> , <code>plums</code>和<code>strawberries</code>键
|
||||
- text: 你应该用<code>delete</code>关键字来移除<code>oranges</code>、<code>plums</code>和<code>strawberries</code>属性。
|
||||
testString: assert(code.search(/oranges:/) !== -1 && code.search(/plums:/) !== -1 && code.search(/strawberries:/) !== -1);
|
||||
|
||||
```
|
||||
@ -46,7 +57,6 @@ let foods = {
|
||||
// change code above this line
|
||||
|
||||
console.log(foods);
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -60,5 +70,20 @@ console.log(foods);
|
||||
|
||||
```js
|
||||
// solution required
|
||||
let foods = {
|
||||
apples: 25,
|
||||
oranges: 32,
|
||||
plums: 28,
|
||||
bananas: 13,
|
||||
grapes: 35,
|
||||
strawberries: 27
|
||||
};
|
||||
|
||||
delete foods.oranges;
|
||||
delete foods.plums;
|
||||
delete foods.strawberries;
|
||||
|
||||
console.log(foods);
|
||||
```
|
||||
|
||||
</section>
|
||||
|
Reference in New Issue
Block a user