今天的題目當中,不會碰到任何跟頁面呈現有關的程式碼,而是將針對陣列Array
於ECMAScript5中增加的新方法做進一步的認識。
ECMAScript5中增加的陣列新方法,都包含以下的特性:
forEach()
:let testArray = ['a', 123, true];
testArray.forEach(function(item){
console.log(item);
});
//a
//123
//true
map()
:let testArray = [1, 2, , 4, 5];
let mapArray = testArray.map(function(item){
return item*item;
});
console.log(mapArray);
//[1, 4, empty, 16, 25]
filter()
: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]
every()
: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
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
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()
為此次課題中會使用到的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)
}
})
首先從草稿中可以看到作者已經先給了兩個陣列。
第一個陣列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():
雖然今天的課題比較不生動,但這些陣列方法在處理資料時的都是非常有幫助的,希望在完成這篇課題之後,大家都能對這幾個陣列方法有更多的認識。