[JavaScript] How does the array traversal method traverse a sparse array

Table of contents

Summary of array traversal methods

1.forEach

2.map

3.for...of / for...in

4.some

5.every

6.filter

7.find

8.findIndex

9.reduce

10. Summary


Summary of array traversal methods

1.forEach

method executes the given function once for each element of the array

Usage: Pass in three parameters to the callback function in turn: the current value of the array, the index of the current item in the array, and the array object

arr.forEach(callback(currentValue [, index [, array]]))

have to be aware of is

  1. forEach() will not change the original array when called, although the callback function may change the original array when called
  2. forEach() always returns undefined and cannot be chained
  3. Do not perform any operations on uninitialized values ​​(sparse arrays), skip the callback function directly
let items = [1, 2,, 4]
let num = 0

let temp = items.forEach(ele => {
    console.log(ele)
    num++
})

console.log("num: " + num)
console.log("temp: " + temp)

// 1
// 2
// 4
// num: 3 跳过了未初始化的值,只执行了3次
// temp:undefined

2.map

method creates a new array whose result is the value returned by invoking the provided function once for each element in the array

用法:
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
 // Return element for new_array 
})

important point:

  1. When map is called, the original array will not be changed, and a new array will be generated and returned
  2. Never been assigned a value will not be called callback
  3. When the callback does not return a value, the new array will also retain the item, the value is undefined
  4. When encountering a sparse array, map() will skip the empty space, but will keep this value
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots的值为[1, 2, 3], numbers的值仍为[1, 4, 9]

var items= [1, 2,, 4,];
var filteredNumbers = items.map(function(num, index) {
  if(index < 3) {
     return num;
  }
});
console.log(filteredNumbers) // [1, 2, , undefined]

There is an easy mistake to make, such as:

["1", "2", "3"].map(parseInt);

 Expected output [1, 2, 3] The actual result is [1, NaN, NaN]

Here parseInt actually receives two parameters of currentValue and index as a callback function

// parseInt(string, radix) -> map(parseInt(value, index))
/* 第一次 (index is 0): */ parseInt("1", 0); // 1     当radix参数为0,parseInt() 会根据十进制
/* 第二次 (index is 1): */ parseInt("2", 1); // NaN  当radix该参数小于 2 或者大于 36 返回NaN
/* 第三次 (index is 2): */ parseInt("3", 2); // NaN  用2进制来解析,应以 0 和 1 开头,所以结果为 NaN


// 解决办法:
function returnInt(element) {
  return parseInt(element, 10);
}

['1', '2', '3'].map(returnInt); // [1, 2, 3]

// 还可以用更简单的方法避免陷阱:
['1', '2', '3'].map(Number); // [1, 2, 3]

3.for...of / for...in

for...of creates an iteration loop on iterable objects (including Array, Map, Set, String, TypedArray, arguments objects, etc.), calls custom iteration hooks, and executes statements for the values ​​of each distinct property

for...in traverses an object's enumerable properties other than Symbol in any order

The difference between for...of and for...in

  1. The order of for...in iterations is not necessarily in order. If the array is iterated and accessed in an important order, it is best to use integer indexes for for loops, forEach, for...of
  2. for..in returns all enumerable properties, including those on the prototype chain
  3. The for...in loop is the key, and the for...of loop is the value
// for...in 语句以任意顺序迭代对象的可枚举属性。

// for...of 语句遍历可迭代对象定义要迭代的数据。

Object.prototype.objCustom = function() {}; 
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = 'hello';

for (let i in iterable) {
  console.log(i); // 0, 1, 2, "foo", "arrCustom", "objCustom"
}

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); // 0, 1, 2, "foo"
  }
}

for (let i of iterable) {
  console.log(i); // 3, 5, 7
}

4.some

The method tests whether at least 1 element in the array passes the provided function test. It returns a value of type Boolean

important point:

  1. some will not change the original array
  2. An empty array call returns false in any case
  3. When encountering a sparse array, map() will skip the empty space and not execute the callback function
  4. The length of the array traversed by some has been determined when the callback is executed for the first time, so the value added to the array in the callback will not be accessed by the callback, and the deleted value will not be accessed
function isBiggerThan10(element, index, array) {
  return element > 10;
}

[2, 5, 8, 1, 4].some(isBiggerThan10);  // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true

// 使用箭头函数更简洁的写法
[2, 5, 8, 1, 4].some(x => x > 10);  // false
[12, 5, 8, 1, 4].some(x => x > 10); // true

// 空数组
[].some(x => x < 10) // false

//第一次执行回调已经确定元素的范围,新增的不会被访问到
let item = [1, 2, 5]
let isBiggerThan = item.some(x => {
    item.push(20)
    return x > 10
})
console.log(item) // [1, 2, 5, 20, 20, 20]
console.log(isBiggerThan) // false


// 已经被删除的元素也不会被访问到
var item = [1, 2, 15]
let isBiggerThan = item.some(x => {
	item.pop() // 删除最后一项元素
	return x > 10
})
console.log(item) // [1]
console.log(isBiggerThan) // false

5.every

method to test whether all elements in an array pass the test of a specified function. Returns a boolean value.

important point:

  1. every will not change the original array
  2. When encountering a sparse array, the callback function will directly skip the empty space
  3. Same as some, the length of the traversed array has been determined when the callback is executed for the first time, the value added to the array in the callback will not be accessed by the callback, and the deleted value will not be accessed
  4. Empty array call returns true in any case
// 空数组
[].every(x => x < 10) // true

// 稀疏数组,跳过未赋值的值
[13,,20].every(x => x > 10) // true

6.filter

method creates a new array containing all elements of the tests implemented by the provided function.

important point:

  1. filter does not change the original array, only returns the new filtered array
  2. callback will only be called on the assigned index, and will not be called on those indexes that have been deleted or have never been assigned
  3. Same as some and every, the length of the traversed array has been determined when the callback is executed for the first time, the value added to the array in the callback will not be accessed by the callback, and the deleted value will not be accessed
function isBigEnough(element) {
  return element >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44] 

7.find

Method returns the value of the first element in the array that satisfies the provided test function. Otherwise return undefined

important point:

  1. The find method does not change the original array
  2. When the sparse array calls the find method, the callback function will not skip the index without value, which means that the find method is less efficient than those methods that only traverse the index with value
  3. The first call determines the index range, new elements added to the array will not be accessed by callback, and deleted values ​​will still be accessed (undefined)
// 稀疏数组,不会跳过
let num = 0;
let hasRight [1,2,3,,5].find(x => {
    console.log(num) // 0 1 2 3 4
    num++
    return x > 5
})
console.log(hasRight) // undefined
 

8.findIndex

Method returns the index of the first element in the array that satisfies the provided test function. Otherwise -1 is returned.

important point:

  1. findIndex will not change the original array
  2. Indexes of uninitialized values ​​in sparse numbers are not skipped
  3. The index range is determined by the first call, new elements added to the array will not be accessed by callback, and deleted values ​​will still be accessed
const array1 = [5, 12, 8, 130, 44];

const isLargeNumber = array1.findIndex(element => element > 13); // 3

9.reduce

method executes a reducer function provided by you (in ascending order) for each element in the array , aggregating its results into a single return value.

Usage: reduce accepts two parameters, namely callback ( reducer), initial value initialValue (optional)

  1. The reducer accepts 4 parameters, which are Accumulator accumulator, CurrentValue current value, CurrentIndex current index, SourceArray original array
  2. initialValue, as the value of the first parameter when the callback function is called for the first time, if not passed, the default value is the first element of the array

important point:

  1. reduce will not change the original array
  2. reduce skips indices of uninitialized values ​​in sparse numbers
  3. If the array is empty and no initial value is provided, a TypeError will be thrown
  4. If the array has only one element and no initial value, or an initial value is provided but the array is empty, reduce returns the unique value without executing the callback
  5. If no initial value is provided, reduce will execute the callback method starting from index 1, skipping the first index. If an initial value is provided, it starts at index 0.
  6. To accumulate properties of an array of objects, an initial value must be provided
[0, 1, 2, 3, 4].reduce((prev, curr) => prev + curr ); // 10

// 提供初始值
[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => { 
    return accumulator + currentValue; 
}, 10 ); // 20

// 箭头函数
[ 0, 1, 2, 3 ].reduce(
  ( acc, cur ) => acc + cur,
  0
);

// 空数组
[].reduce((prev, curr) => prev + curr ); // TypeError

// 提供了初始值
[].reduce((prev, curr) => prev + curr, 20 ); // 20

// 数组长度为1
[15].reduce((prev, curr) => prev + curr ); // 15

//累加对象数组
var initialValue = 0;
var sum = [{x: 1}, {x:2}, {x:3}].reduce(function (accumulator, currentValue) {
    return accumulator + currentValue.x;
},initialValue)

console.log(sum) // 6

// 无初始值,得到不是期望的返回
var sum = [{x: 1}, {x:2}, {x:3}].reduce(function (accumulator, currentValue) {
    return accumulator + currentValue.x;
})

console.log(sum) // "[object Object]23"

10. Summary

               forEach map for...of for...in some every filter find findIndex reduce
Whether to change the original array × × × × × × × × × ×
Is there a return value × × ×
return type × Array × × Boolean Boolean Array value/undefined index/-1 accumulated value
sparse array jump over skip, leave blank normal traversal jump over jump over jump over jump over normal traversal normal traversal normal traversal

Guess you like

Origin blog.csdn.net/haidong55/article/details/106525984