0%

JS 找出元素索引值的陣列 Array 方法 indexOf()

Day 27

那一排,都是穿黑衣戴口罩的,去幫我找出搗亂的。抱歉,我只能給你 -1 因為連我們偶爾都會穿黑衣戴口罩。

終於,我們要進入 ECMAScript 5 的陣列方法了!
ECMAScript 5 定義了許多很重要的陣列方法,包括了過濾、檢測、遍歷、搜索和鏡射的方法,讓我們能更輕易的操控陣列與陣列元素。

但是今天是週末,我們先來介紹相對比較沒那麼複雜的indexOf()

indexOf()方法像是一個會通風報信的吹哨人,請它去幫忙找出陣列裡面的某個指定元素,它就會 明查暗訪 幫我們把這個元素找出來,並告訴我們這個元素在哪個位置(索引值),它只會給我們「第一個」找到的位置 表示有交差,如果沒有找到,indexOf()就會回傳給我們 -1 表示在陣列裡找不到這個元素。

Array.prototype.indexOf() - JavaScript | MDN

陣列處理方法集合

原型: Array.prototype.indexOf()
功能: 搜尋陣列中指定的值。
改變: 不會改變原陣列。
語法: arr.indexOf(searchElement[, fromIndex])
回傳值: 在陣列中找到的第一個元素索引值;沒找到則為 -1。
參數: 要找的元素、從哪裡開始找。

為了不混淆,我們以字串元素來示範

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const arr = ['a', 'b', 'c', 'D', 'C', 'b', 'a'];

// 沒給參數,不知道我們要找的元素是什麼,回傳 -1 很合理。
arr.indexOf(); // -1

// 找到的 "c" 在索引值 2 的位置
arr.indexOf('c'); // 2

// 從索引值 2 的位置開始找,所以找到第二個 "b"
arr.indexOf('b', 2); // 5

// 從索引值 3 的位置開始找,會區分大小寫,找不到 "c" 回傳 -1
arr.indexOf('c', 3); // -1

// 第二參數預設就是 0 ,這裡有寫沒寫都ㄧ樣
arr.indexOf('c', 0); // 2

// 第二參數 -5 表示從後面數過來 -5 的位置開始找,所以找得到 "c"
arr.indexOf('c', -5); // 2

// 但是從 -5 開始找就找不到"c" 所以回傳 -1
arr.indexOf('c', -4); // -1

參數的規則很直覺

indexOf()可帶兩個參數,第一個參數searchElement是指定要找尋的元素,第二個參數fromIndex索引值,不是必須,表示要從哪一個位置開始搜尋。如果這個索引值大於或等於陣列的長度,會直接回傳 -1,因為要開始搜尋的元素都已經超過陣列長度,自然搜尋就起不了作用。

如果給的fromIndex索引值是一個負數,就會從陣列的最後一個往回算,等同最後一個的索引值是 -1,以此類推。

雖然表示往回算,但indexOf()的搜尋順序依然會從陣列的左往右一一搜尋。如果負數索引值在回頭計算之後仍然小於 0,則會從左往右全部搜尋。

這個參數的預設值為 0(即搜尋整個陣列)。還有,indexOf()並不像其他大部分的 ECMAScript 5 陣列方法一樣,參數可以帶函式,帶函式參數對indexOf()是無效的。

找出所有陣列裡指定的索引值

雖然indexOf()只會回傳給我們第一個找到的元素位置,但是我們可以使用迴圈,將陣列裡面所有符合搜尋條件元素的索引值,放在一個陣列裡:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function findAll(arr, element) {
const results = [];
let len = arr.length;
let fromIndex = 0;
while (fromIndex < len) {
fromIndex = arr.indexOf(element, fromIndex);
if (fromIndex === -1) break; // 沒找到完成搜尋
results.push(fromIndex); // 將找到的索引值放入陣列
fromIndex = fromIndex + 1;
}
return results;
}

let result = findAll(arr, 'b');
result; // [1, 5]

如果可以將找到的索引位置的值,集中放入陣列裡是不是更方便?indexOf()雖然無法直接做到,但是有其他方法可以做到這些,例如 ECMAScript 5 的filter或 ECMAScript 6 的find()都可以輕易辦到。

參考型別的元素找法

和某些部分陣列的方法ㄧ樣,indexOf()是無法直接查找參考型別的元素,像是陣列、物件,需要將這些元素指定給一個變數,這個變數在陣列裡,就可使用indexOf()到。

1
2
3
4
5
6
7
8
9
10
11
12
13
const arr2 = ['a', { a: 42 }];

arr2.indexOf('a'); // 0 找得到
arr2.indexOf({ a: 42 }); // -1 找不到

// 將元素指定給變數
const arr = [1, 2];
const arr3 = [42, arr];
arr3.indexOf(arr); // 1

const obj = { a: 42 };
const arr4 = ['a', obj, 12];
arr4.indexOf(obj); // 1

其實,還有另一個indexOf()的孿生陣列方法lastIndexOf()功能和indexOf()差不多 簡直ㄧ樣,我們明天可以來聊聊,順便穿插一些輕鬆題外話~敬請期待囉~

才剛要介紹 ECMAScript 5 的陣列方法,鐵人賽就快要結束了,那 ECMAScript 6 呢? 不長進的留到明年寫嗎? 參加鐵人賽所獲得的,也不只是介紹這些方法而已。因鐵人賽讓本人開始了解查找資料的樂趣 大嬸瘋了 所以,應該會繼續不定期寫下去喔~

如有需要改進的地方,拜託懇求請告知,我會盡量快速度修改,感謝您~

開頭的那句開場白,寫的時候有點心驚驚,會不會太敏感、會不會太表明立場?所謂民主,應該是不需要懼怕這些的,所謂民主,應該是可以讓人們自由的發表言論而不被壓抑,民主的另一種姿態是勇敢,勇敢捍衛這些得來不易的自由。 這些絕對不是要湊字數 XD