iT邦幫忙

2022 iThome 鐵人賽

DAY 20
0
Modern Web

從新開始學習p5.js畫出一片天系列 第 20

D20_陣列資料操作[資料逐筆處理,搜尋,篩選,轉換]

  • 分享至 

  • xImage
  •  

陣列資料操作[資料逐筆處理,搜尋,篩選,轉換]

今天來整理陣列的元素操作

基本的迴圈模式開始

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的操作

在陣列中,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);

會直接複製一份獨立的陣列,算是最簡捷的方法了。

var, let, const

目前在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種,

  1. 一種是直接修改回原本的陣列元素內容
  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


上一篇
D19_陣列資料操作[基本概念,資料排序]
下一篇
D21_事件觸發操作[鍵盤]
系列文
從新開始學習p5.js畫出一片天40
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言