Home > Web Front-end > JS Tutorial > body text

Code examples detailing interesting JavaScript native array functions

黄舟
Release: 2017-03-06 14:37:59
Original
1453 people have browsed it

In JavaScript, you can use the Array constructor to create an array, or use the array literal [], the latter is the preferred method. The Array object inherits from Object.prototype, and executing the typeof operator on the array returns object instead of array. However, []instanceof Array also returns true. In other words, the implementation of array-like objects is more complex, such as strings objects and arguments objects. The arguments object is not an instance of Array, but has a length attribute and can obtain values ​​through indexes, so it can be looped like an array.
In this article, I will review some of the array prototype methods and explore their uses.

  • Loop: .forEach

  • Judgement: .some and .every

  • Distinguish between .join and .concat

  • Stack and queue implementation: .pop, .push, .shift, and .unshift

  • Model mapping: .map

  • Query: .filter

  • Sort: .sort

  • Calculation: .reduce and. reduceRight

  • Copy: .slice

  • Powerful .splice

  • Find: .indexOf

  • Operator: in

  • Approach.reverse

Loop:.forEach

This is the simplest method in JavaScript, but IE7 and IE8 do not support this method.

.forEach has a callback function as a parameter. When traversing the array, it will be called for each array element. The callback function accepts three parameters:

  • ##value: current Element

  • index: the index of the current element

  • array: the array to be traversed

In addition , you can pass an optional second parameter as the context (this) of each function call.

['_', 't', 'a', 'n', 'i', 'f', ']'].forEach(function (value, index, array) {
    this.push(String.fromCharCode(value.charCodeAt() + index + 2))
}, out = [])
out.join('')
// <- &#39;awesome&#39;
Copy after login

will be mentioned later.join, in this example, it is used to splice different values ​​in the array element, the effect is similar to out[0] + ” + out[1] + ” + out[2] + ” + out[n].

Cannot interrupt the .forEach loop, and it is unwise to throw an exception Choice. Fortunately we have another way to interrupt the operation: .some and .every

If you have used enumerations in .NET, these two methods are the same. .Any(x => , and also has an optional second context parameter. MDN describes .some as follows:

some will execute the callback function once for each element in the array until the callback function returns true. . If the target element is found, some returns true immediately, otherwise some returns false. The callback function is only executed on the array index with a specified value; it will not be called on deleted or unspecified elements.

max = -Infinity
satisfied = [10, 12, 10, 8, 5, 23].some(function (value, index, array) {
    if (value > max) max = value
    return value < 10
})
console.log(max)
// <- 12
satisfied
// <- true
Copy after login
Note that when the value of the callback function is < 10, the function loop is interrupted. The operating principle of .every is similar to that of .some, but the callback function returns false instead of true.

Distinguish between .join and . concat

.join and .concat are often confused. .join(separator) uses the separator as the separator to join the array elements and returns the string form. If the separator is not provided, the default .concat will be used. A new array, used as a shallow copy of the source array. Common usage of .concat: array.concat(val, val2, val3, valn)

#. ##.concat returns a new array

    ##array.concat() returns a shallow copy of the source array without parameters
  • ##. #Shallow copy means that the new array and the original array maintain the same object reference, which is usually a good thing. For example:
  • var a = { foo: &#39;bar&#39; }
    var b = [1, 2, 3, a]
    var c = b.concat()
    console.log(b === c)
    // <- false
    b[3] === a && c[3] === a
    // <- true
    Copy after login
  • Implementation of stack and queue: .pop, .push, .shift and .unshift

    Everyone knows that .push can add elements to the end of the array, but you know that you can use [].push('a', 'b', 'c', 'd', 'z') adds multiple elements at once?
  • .pop method is the reverse operation of .push, it returns the deleted last element of the array. If the array is empty, void 0 (undefined) will be returned. Use .pop and .push to create a LIFO (last in first out) stack.

    function Stack () {
        this._stack = []
    }
    Stack.prototype.next = function () {
        return this._stack.pop()
    }
    Stack.prototype.add = function () {
        return this._stack.push.apply(this._stack, arguments)
    }
    stack = new Stack()
    stack.add(1,2,3)
    stack.next()
    // <- 3
    相反,可以使用.shift和 .unshift创建FIFO (first in first out)队列。
    
    function Queue () {
        this._queue = []
    }
    Queue.prototype.next = function () {
        return this._queue.shift()
    }
    Queue.prototype.add = function () {
        return this._queue.unshift.apply(this._queue, arguments)
    }
    queue = new Queue()
    queue.add(1,2,3)
    queue.next()
    // <- 1
    Using .shift (or .pop) is an easy way to loop through a set of array elements, while draining the array in the process.
    list = [1,2,3,4,5,6,7,8,9,10]
    while (item = list.shift()) {
        console.log(item)
    }
    list
    // <- []
    Copy after login

    Model mapping: .map

.map provides a callback method for each element in the array and returns a new array composed of the call results. The callback function is only executed for array indexes with assigned values; it is not called for deleted or unassigned elements.

Array.prototype.map has the same parameter format as .forEach, .some and .every mentioned above: .map(fn(value, index, array), thisArgument)

values = [void 0, null, false, &#39;&#39;]
values[7] = void 0
result = values.map(function(value, index, array){
    console.log(value)
    return value
})
// <- [undefined, null, false, &#39;&#39;, undefined × 3, undefined]
Copy after login

undefined × 3 explains well that .map will not be called on elements that have been removed or have unspecified values, but will still be included in the resulting array. .map is very useful when creating or changing arrays, see the following example:

// casting
[1, &#39;2&#39;, &#39;30&#39;, &#39;9&#39;].map(function (value) {
    return parseInt(value, 10)
})
// 1, 2, 30, 9
[97, 119, 101, 115, 111, 109, 101].map(String.fromCharCode).join(&#39;&#39;)
// <- &#39;awesome&#39;
// a commonly used pattern is mapping to new objects
items.map(function (item) {
    return {
        id: item.id,
        name: computeName(item)
    }
})
Copy after login

Query: .filter

filter executes the callback function once for each array element and returns a A new array consisting of elements for which the callback function returns true. The callback function will only be called for array items that have specified values.

通常用法:.filter(fn(value, index, array), thisArgument),跟C#中的LINQ表达式和SQL中的where语句类似,.filter只返回在回调函数中返回true值的元素。

[void 0, null, false, &#39;&#39;, 1].filter(function (value) {
    return value
})
// <- [1]
[void 0, null, false, &#39;&#39;, 1].filter(function (value) {
    return !value
})
// <- [void 0, null, false, &#39;&#39;]
Copy after login

排序:.sort(compareFunction)

如果没有提供compareFunction,元素会被转换成字符串并按照字典排序。例如,”80″排在”9″之前,而不是在其后。

跟大多数排序函数类似,Array.prototype.sort(fn(a,b))需要一个包含两个测试参数的回调函数,其返回值如下:

  • a在b之前则返回值小于0

  • a和b相等则返回值是0

  • a在b之后则返回值小于0

[9,80,3,10,5,6].sort()
// <- [10, 3, 5, 6, 80, 9]
[9,80,3,10,5,6].sort(function (a, b) {
    return a - b
})
// <- [3, 5, 6, 9, 10, 80]
Copy after login

计算:.reduce和.reduceRight

这两个函数比较难理解,.reduce会从左往右遍历数组,而.reduceRight则从右往左遍历数组,二者典型用法:.reduce(callback(previousValue,currentValue, index, array), initialValue)。

previousValue 是最后一次调用回调函数的返回值,initialValue则是其初始值,currentValue是当前元素值,index是当前元素索引,array是调用.reduce的数组。

一个典型的用例,使用.reduce的求和函数。

Array.prototype.sum = function () {
    return this.reduce(function (partial, value) {
        return partial + value
    }, 0)
};
[3,4,5,6,10].sum()
// <- 28
Copy after login

如果想把数组拼接成一个字符串,可以用.join实现。然而,若数组值是对象,.join就不会按照我们的期望返回值了,除非对象有合理的valueOf或toString方法,在这种情况下,可以用.reduce实现:

function concat (input) {
    return input.reduce(function (partial, value) {
        if (partial) {
            partial += &#39;, &#39;
        }
        return partial + value
    }, &#39;&#39;)
}
concat([
    { name: &#39;George&#39; },
    { name: &#39;Sam&#39; },
    { name: &#39;Pear&#39; }
])
// <- &#39;George, Sam, Pear&#39;
Copy after login

复制:.slice

和.concat类似,调用没有参数的.slice()方法会返回源数组的一个浅拷贝。.slice有两个参数:一个是开始位置和一个结束位置。
Array.prototype.slice 能被用来将类数组对象转换为真正的数组。

Array.prototype.slice.call({ 0: &#39;a&#39;, 1: &#39;b&#39;, length: 2 })
// <- [&#39;a&#39;, &#39;b&#39;]
这对.concat不适用,因为它会用数组包裹类数组对象。

Array.prototype.concat.call({ 0: &#39;a&#39;, 1: &#39;b&#39;, length: 2 })
// <- [{ 0: &#39;a&#39;, 1: &#39;b&#39;, length: 2 }]
Copy after login

此外,.slice的另一个通常用法是从一个参数列表中删除一些元素,这可以将类数组对象转换为真正的数组。

function format (text, bold) {
    if (bold) {
        text = &#39;<b>&#39; + text + &#39;</b>&#39;
    }
    var values = Array.prototype.slice.call(arguments, 2)
    values.forEach(function (value) {
        text = text.replace(&#39;%s&#39;, value)
    })
    return text
}
format(&#39;some%sthing%s %s&#39;, true, &#39;some&#39;, &#39;other&#39;, &#39;things&#39;)
Copy after login

强大的.splice

.splice 是我最喜欢的原生数组函数,只需要调用一次,就允许你删除元素、插入新的元素,并能同时进行删除、插入操作。需要注意的是,不同于`.concat和.slice,这个函数会改变源数组。

var source = [1,2,3,8,8,8,8,8,9,10,11,12,13]
var spliced = source.splice(3, 4, 4, 5, 6, 7)
console.log(source)
// <- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ,13]
spliced
// <- [8, 8, 8, 8]
Copy after login

正如你看到的,.splice会返回删除的元素。如果你想遍历已经删除的数组时,这会非常方便。

var source = [1,2,3,8,8,8,8,8,9,10,11,12,13]
var spliced = source.splice(9)
spliced.forEach(function (value) {
    console.log(&#39;removed&#39;, value)
})
// <- removed 10
// <- removed 11
// <- removed 12
// <- removed 13
console.log(source)
// <- [1, 2, 3, 8, 8, 8, 8, 8, 9]
Copy after login

查找:.indexOf

利用.indexOf 可以在数组中查找一个元素的位置,没有匹配元素则返回-1。我经常使用.indexOf的情况是当我有比较时,例如:a === ‘a’ || a === ‘b’ || a === ‘c’,或者只有两个比较,此时,可以使用.indexOf:['a', 'b', 'c'].indexOf(a) !== -1。

注意,如果提供的引用相同,.indexOf也能查找对象。第二个可选参数用于指定开始查找的位置。

var a = { foo: &#39;bar&#39; }
var b = [a, 2]
console.log(b.indexOf(1))
// <- -1
console.log(b.indexOf({ foo: &#39;bar&#39; }))
// <- -1
console.log(b.indexOf(a))
// <- 0
console.log(b.indexOf(a, 1))
// <- -1
b.indexOf(2, 1)
// <- 1
Copy after login

如果你想从后向前搜索,可以使用.lastIndexOf。

操作符:in

在面试中新手容易犯的错误是混淆.indexOf和in操作符:

var a = [1, 2, 5]
1 in a
// <- true, but because of the 2!
5 in a
// <- false
Copy after login

问题是in操作符是检索对象的键而非值。当然,这在性能上比.indexOf快得多。

var a = [3, 7, 6]
1 in a === !!a[1]
// <- true
Copy after login

走近.reverse

该方法将数组中的元素倒置。

var a = [1, 1, 7, 8]
a.reverse()
// [8, 7, 1, 1]
Copy after login

.reverse 会修改数组本身。

参考

《Fun with JavaScript Native Array Functions》

以上就是详细介绍有趣的JavaScript原生数组函数的代码示例的内容,更多相关内容请关注PHP中文网(www.php.cn)!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!