iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 4
1

Day4-課題內容

今天的題目當中,不會碰到任何跟頁面呈現有關的程式碼,而是將針對陣列Array於ECMAScript5中增加的新方法做進一步的認識。

ECMAScript5 陣列方法

ECMAScript5中增加的陣列新方法,都包含以下的特性:

  1. 這些方法的第一個引數大多為函示。
  2. 會對陣列中每個或是部分元素調用一次函式。
  3. 如果是稀疏陣列,不存在的元素則不會調用函示。

新陣列方法簡介

  1. forEach():
    此方法會逐一查用陣列中的每個元素,並針對每個元素調用指定的函式。
let testArray = ['a', 123, true];
testArray.forEach(function(item){
    console.log(item);
});
//a
//123
//true
  1. map():
    此方法會把陣列中的每個元素逐一調用,最後回傳一個由函式回傳值所組成的陣列,如果為稀疏陣列,原本的缺口也會被保留。
let testArray = [1, 2, , 4, 5];
let mapArray = testArray.map(function(item){
    return item*item;
});
console.log(mapArray);
//[1, 4, empty, 16, 25]
  1. filter():
    此方法會把陣列中的每個元素經由指定判斷式來確認,最後回傳包含所有判斷值為true元素的陣列。
let testArray = [1, 5, 10, 8, 21];
//第一種寫法
let filterArray = testArray.filter(function(item){
    if(item > 7) {
        return item;
    };
});
//第二種寫法
let filterArray = testArray.filter(function(item){
        return item > 7;
});
console.log(filterArray);
//[10, 8, 21]
  1. every():
    此方法會經由指定的判斷式來確任陣列中的每個元素,如果每個元素調用判斷式的回傳值皆為true則回傳true,否則則為false。
let testArray = [3, 4, 5, 6, 7];
let trueArray = testArray.every(function(item){
    if(item > 2){
        return item
    };
});
let falseArray = testArray.every(function(item){
    if(item > 6){
        return item
    };
});
console.log(trueArray); //true
console.log(falseArray); //false
  1. some():
    此方法功能與every()類似,但只要有一個元素的回傳值為true就回傳true,若是都無則回傳false。
let testArray = [3, 4, 5, 6, 7];
let trueArray = testArray.some(function(item){
    if(item > 6){
        return item
    };
});
let falseArray = testArray.some(function(item){
    if(item > 7){
        return item
    };
});
console.log(trueArray); //true
console.log(falseArray); //false
  1. reduce() or reduceRight():
    此方法會依據指定的函式,從左到右或從右到左,結合陣列中的元素,最後回傳一個值。
array.reduce(function(accumulator, currentValue, currentIndex, array){},initial Value)
accumulator:累加器,為前次函式所回傳的先前值或者是初始值。
currentValue:目前處理元素的值。
currentIndex:目前處理元素的索引值。有給定初始值,由0開始,無初始值則由1開始。
initial Value:初始值。
let testArray = [2, 3, 4, 5, 6];
let reduceArray = testArray.reduce(function(accumulator, currentValue){
    return accumulator + currentValue;
});
console.log(reduceArray); //20

sort()方法

sort()為此次課題中會使用到的ECMAScript3陣列方法,此方法會將原陣列上的元素排序,並回傳排序後的陣列。若呼叫時不帶條件,會依字首的字體大小寫與字母順序,或數值大小來排列。

let testArray = ['apple', 'banana', 'Cat', 'Dog'];
let sortArray = testArray.sort();
console.log(sortArray);//["Cat", "Dog", "apple", "banana"]

如果給定條件,則依據return的值決定順序:

array.sort(function(a, b){
    if(a的值 > b的值){
    return > 0 (a.index > b.index)
    return = 0 (a.index與b.index不變)
    return < 0 (a.index < b.index)
    }
})

進入JS30-Day4

首先從草稿中可以看到作者已經先給了兩個陣列。
第一個陣列inventors,是由人物資料組合而成的物件,作為元素所組成的陣列。第二個陣列people,則是由名字字串作為元素所組合而成。

第一題:

Filter the list of inventors for those who were born in the 1500's。
我們透過filter()這個方法,設定符合的條件之後,便能篩選出符合的物件,而這邊作者使用了console.table()的方法,可以讓我們將資料以表格的方式呈現:

let personFilter = inventors.filter(function (person) {
      if(person.year >= 1500 && person.year < 1600) {
          return person;
      };
});
console.table(personFilter);

第二題:

Give us an array of the inventors' first and last names。
透過map(),將我們想取得的資料組合起來,最後回傳一個陣列:

let personName = inventors.map(function (person) {
        return `${person.first} ${person.last}`;
    });
console.log(personName);

第三題:

Sort the inventors by birthdate, oldest to youngest。
要比較年齡的大小,可以使用sort()方法,並利用出生年份來判斷:

let personBirthdayRank = inventors.sort(function (a, b) {
    if(a.year > b.year) {
        return 1;
    //出生年份比較大的排在後面
    } else {
        return -1;
    //出生年份比較小的排在前面
    }
});
console.table(personBirthdayRank);

第四題:

How many years did all the inventors live?
利用reduce()方法,將每個人的壽命時間加總起來:

let totalYear = inventors.reduce(function(accumulator, currentValue) {
    return accumulator + (currentValue.passed - currentValue.year)}, 0)
console.log(totalYear);

第五題:

Sort the inventors by years lived。
利用sort()方法,將每個人的壽命計算出來之後,進行排序:

let personLivingYear = inventors.sort(function (a, b) {
    if((a.passed - a.year) > (b.passed - b.year)) {
        return 1;
    }
});
console.table(personLivingYear);

第六題

create a list of Boulevards in Paris that contain 'de' anywhere in the name。
https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris
首先利用document.querySelectorAll,將每一個符合的元素選取起來,此時我們會得到一包含所有被選到元素的物件,然後利用Array.from()方法,將取得的物件轉為陣列:

let getAllItems = document.querySelectorAll('.mw-category a');
let webArray = Array.from(getAllItems);

再來建立一空的陣列,然後利用forEach()的方法,將webArray每個元素的字串,加入我們建立的新陣列,如此一來,新的陣列便會包含所有元素的字串資料:

let stringArray = [];
webArray.forEach(function(item){
    stringArray.push(item.innerHTML);
});

這邊也可以使用map的方法,回傳含有各元素innerHTML的陣列,一樣可以得到相同的陣列:

let stringArray = webArray.map(function(item){
      return item.innerHTML;
});

最後再利用filter()方法,將每個字串元素,判斷是否含有'de'這個短字串:

let deArray = newArray.filter(function(streetName) {
    if (streetName.includes('de'))
    return streetName;
});

第七題

Sort the people alphabetically by last name。
在people這個陣列當中,每個元素為"firstName, lastName"這種格式的字串,為了單獨取得lastName,我們必須使用到字串的split()方法。這個方法,會去尋找符合的字元,然後將原本的字串,於符合的字元的地方,分開成陣列:

let testString = 'a,b,c,d,e';
let splitArray = testString.split(',');
console.log(splitArray);
// ["a", "b", "c", "d", "e"]

首先,先把原本包著字串元素的陣列,利用map()的方法,得到一包著許多陣列的陣列:

let newPeopleArray = people.map(function(person){
    return person.split(', ');
});

完成之後,我們便可以針對小陣列中,第二的元素進行排序:

let organizeArray= newPeopleArray.sort(function(a, b){
    if(a[1] > b[1]) {
        return 1;
    } else {
        return -1;
    }
});
console.table(organizeArray);

第八題

這個題目,作者希望我們透過reduce()方法,將data陣列中的資料,做出一個統計結果。
透過將reduce()方法中的初始值指定為一個物件,並將currentValue指定為物件中的屬性,如此一來我們便能回傳物件中屬性的資料,完成統計的動作:

let summary = data.reduce(function(object, item){
    //假如物件中還沒有該屬性 變創造該屬性且值為0
    if(object[item] === undefined){
        object[item] = 0;
    }
    //每取得對應屬性一次,對應的屬性值+1
    object[item]++;
    //最後再將目前物件的狀態回傳回去
    return object;
}, {})
console.log(summary);

這邊提供另外一個方法,則是透過forEach()的方法,一樣做出透過更動物件中的屬性值,來完成統計:

//指定一空的物件
let transport = {};
//使用forEach()方法,將物件屬性加入物件當中
data.forEach(function(vehicle){
    //若該屬性尚未存在,則創造該屬性並該屬性值為1(已經計算到1次)
    if(transport[vehicle] === undefined){
        transport[vehicle] = 1;
    //若該屬性已經存在,則該屬性值加1
    } else {
        transport[vehicle]++;
    }
});
console.log(transport);

總結

在今天的一系列燒腦陣列課題當中,我們學到幾個陣列的方法:
1.forEach():
2.map():
3.filter():
4.every():
5.some():
6.reduce(): or reduceRight():
7.sort():

雖然今天的課題比較不生動,但這些陣列方法在處理資料時的都是非常有幫助的,希望在完成這篇課題之後,大家都能對這幾個陣列方法有更多的認識。

參考資料

  1. javascript30
  2. MDN文件

上一篇
JS30-Day3-CSS Variables
下一篇
JS30-Day5-Flex Panels
系列文
新手也能懂的JS3030

1 則留言

0
陳董 Don
iT邦新手 5 級 ‧ 2017-12-23 16:42:39

素晴らしい~

我要留言

立即登入留言