今天來整理陣列的元素操作
const arr = [1, 2, 3, 4, 5, 6, 7];
若要依序印出,有以下3種處理方式
i是陣列的流水號編號,x是陣列的元素內容
const arr = [1, 2, 3, 4, 5, 6, 7];
function setup() {
//-- type1 --
for(let i=0; i<arr.length; i++){
let x = arr[i];
console.log(i+": "+x);
}
//-- type2 --
let i = 0;
for(x of arr){
console.log(i+": "+x);
i++;
}
//-- type3 --
arr.forEach((x, i) =>{
console.log(i+": "+x);
});
}
接著是想要將陣列複製clone一份
const arr = [1, 2, 3, 4, 5, 6, 7];
function setup() {
//-- type1 --
const arr_copy1 = [];
for (let i = 0; i < arr.length; i++) {
arr_copy1[i] = arr[i];
}
console.log(arr_copy1);
//-- type2 --
const arr_copy2 = [];
for (x of arr) {
arr_copy2.push(x);
}
console.log(arr_copy2);222
//-- type3 --
const arr_copy3 = [];
arr.forEach( x => {
arr_copy3.push(x);
});
console.log(arr_copy3);
//-- type4 --
const arr_copy4 = arr.map(x => x);
console.log(arr_copy4);
}
在陣列中,copy, clone, duplicate的操作,
並不能以一個簡單的「=」來處理,
const arr_copy = arr;
這樣只是多一個變數名稱指向同一個陣列。
例如原本 arr[2] = 4; arr_copy[2] = 6; 時,
arr[2]就會改成 6了
所以如果要將一個陣列複製一份完全獨立的陣列的話,
就要建立一個新的陣列,再將原陣列的資料複製到新陣列中。
複製的方法是使用 arr_copy.push(x);的方式處理
不過需要搭配 for迴圈的方式
但是也有更簡捷的方式,
arr.forEach( x => {
arr_copy.push(x);
});
arr.forEach() 的結果 相當於
for (x of arr) {
arr_copy.push(x);
}
仍需要執行 arr_copy.push(x);
而
const arr_copy = arr.map(x => x);
會直接複製一份獨立的陣列,算是最簡捷的方法了。
目前在JS中有3種宣告變數的方式,3種之間的差異,主要是跟變數的宣告初值與使用範圍有關
變數在宣告的時候,是否就要設定初值,設定之後,是否還可以重新宣告,變數的操作區塊範圍,
有分全域或是區域,
宣告種類 | 是否宣告就要設定初值 | 是否可以重覆宣告 | 是否有操作範圍限制 |
---|---|---|---|
var | 不用,可以需要時再設定 | 可以,後宣告的會覆寫先前宣告的 | 沒有,不管在什麼程式區段,改變變數的內容會影響全部相同變數名稱的內容 |
let | 要設定初值,設定後可以更改變數內容 | 不能用let重覆宣告同一變數,但是可以在不同的程式區段宣告 | 有分全域宣告或是區域宣告,改變變數的內容只會影響該區域內宣告的變數,因此,全域宣告或是區域宣告互相不會影響。 |
const | 要設定初值,並且設定後就不能更改變數內容 | 不能用const重覆宣告同一變數,但是可以在不同的程式區段宣告 | 有分全域宣告或是區域宣告 |
在陣列中,要用const來宣告,像是 物件也是要用const來宣告,
看起來像是不能更陣列的資料,但其實是指不能重覆宣告陣列,或是以[1, 2, 3]的形式更改陣列內容
像是以下操作是錯誤的
const arr = [1, 2, 3];
const arr = [4, 5, 6]; //-- 重覆宣告陣列
arr = [7, 8, 9]; //-- 更改陣列內容
但是單獨更改陣列中的元素內容是可以的,
像是以下操作是可以的
const arr = [1, 2, 3];
arr[0] = 4;
arr[1] = 5;
arr[2] = 6;
一般來說,陣列的資料處理方式有2種,
常見的陣列資料處理有
計算,搜尋,篩選,轉換
計算是將陣列資料取出,經過計算將結果顯示出來,或是傳送給其他物件使用。
像是要計算陣列元素數值的平均值
let total = 0;
let ave = 0;
let n = 0;
for (x of arr) {
total += x;
n++;
}
ave = total/n;
console.log("ave: "+ave);
或是將原資料篩選出奇數的元素
使用for loop方法
for (x of arr) {
if(x%2==1){
console.log(x);
}
}
使用 iterator 迭代器方法
arr.filter 是一種陣列迭代的用法
語法如下
arr.filter( (item) => condition );
arr.filter( (item, index) => condition );
arr.filter( (item, index, array) => condition );
arr.filter( (item) => { return condition; } );
或是
arr.filter(odd_find);
function odd_find(item){
return condition;
}
//----
const arr_odd1 = arr.filter( (x) => x%2==1 );
console.log(arr_odd1);
//----
const arr_odd2 = arr.filter( (x) => { return x%2==1; } );
console.log(arr_odd2);
//----
const arr_odd3 = arr.filter(odd_find);
function odd_find(x){
return x%2==1;
}
console.log(arr_odd3);
基本上採用 iterator 迭代器方法的語法都是相同的。
目前常用的陣列迭代器方法的功能有
const arr = [1, 2, 3, 4, 5, 6, 7];
arr.forEach( (item) => { console.log(item); });
const arr_filter = arr.filter( (item) => { return item%2==1; });
console.log(arr_filter);
const arr_map = arr.map( (item) => { return item+100; });
console.log(arr_map);
const arr_num = [33, 2, 6, 44, 54];
let val_sum = arr_num.reduce((total, value, index, array) => { return total + value; });
console.log(val_sum); //-- 139
let arr_allOver20 = arr_num.every((value, index, array) => { return value > 20; });
console.log(arr_allOver20); //-- false
let arr_someOver20 = arr_num.some((value, index, array) => { return value > 20; });
console.log(arr_someOver20); //-- true
let arr_first = arr_num.find((value, index, array) => { return value > 18; });
console.log(arr_first); //-- 33
const animal = ["dog", "cat", "bird", "fish"];
let val_position = animal.indexOf("cat") + 1;
console.log(val_position); //-- 2
const arr_keys = Array.from(animal.keys());
console.log(arr_keys);
const arr_entries = Array.from(animal.entries());
console.log(arr_entries);
const arr_str = Array.from("ABCDEFG");
console.log(arr_str);
其中
Array.from(animal.keys()); 可以將 Map 物件格式轉換成陣列
Array.from("ABCDEFG"); 可以將 字串 格式轉換成陣列
animal.keys() 可以取得 陣列中的key 流水號集合
animal.entries() 可以取得 陣列中的entry 元素內容集合
這些都是可以將原本較繁複的for loo語法,
轉換成以陣列 iterator 迭代器的語法,可以變得更簡潔。
//------------------
在p5.js的陣列功能大部份都已 deprecated (不建議使用)
改以原JS在陣列上的操作方法
以下是對照表
p5.js | Native JS |
---|---|
append() | array.push(value) |
arrayCopy() | array.map(x => x) |
concat() | arr1.concat(arr2) |
reverse() | array.reverse() |
shorten() | array.pop() |
shuffle() | |
sort() | array.sort() |
splice() | array.splice() |
subset() | array.slice() |
shuffle(): 產生隨機的陣列排序順序
參考資料
JavaScript Array Reference
https://www.w3schools.com/jsref/jsref_obj_array.asp
Array.from()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
Array.prototype.fill()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill