As the foundation of JS, array is a basic that every front-end programmer needs to master. As a front end small white, no matter when just started, or now contact the project, or practice the simple array algorithm problem, as soon as I see the code or problem, my mind often only think of the for loop, the logic is obscure, the code is huge and redundant, it is difficult to get started. A big reason is that the array method is not used proficiently, sometimes a large string of code, just need to borrow the array method and change can become simple, efficient and elegant. So I’m going to summarize the common methods of arrays here

So array operations, the first thing we need to notice and keep in mind is that splice, sort, reverse these three common methods are operations on the array itself, they change the array itself

Common methods for arrays

  • Add/Remove elements:

    • push(… Items): adds an element from the end and returns the new length
    • Pop (): deletes the last element of an array and returns the deleted element
    • Shift (): removes the element from the beginning and returns the value of the first element
    • unshift(… Items): Adds an element from the beginning and returns the new length
    • splice(pos,deleteCount,… Items): delete from index, delete the deleteCount element, and insert one or more elements at the current position. If only the element is deleted, an array containing the deleted elements is returned, otherwise empty
    • Slice (start,end): It copies from index “start” to “end” (excluding “end”) and returns a new array
    • concat(… Items): returns a new array: copies all the members of the current array and adds items to all the members. If any items are an array, then take all their elements
  • Query element:

    • IndexOf (item,pos): retrieve item from pos position, return index if there is one; otherwise return -1; If pos is not set, it starts at 0 by default
    • LastIndexOf (Item,pos): retrieve item from pos position, return index otherwise return -1; If pos is not set, it starts with length-1 by default
    • Includes (value) : Return true if the array has value, false otherwise
    • Find /filter(func): Filters elements through the function, returning the first value that matches find or all the values that match filter
    • FindIndex (func): Similar to find, but it returns an index instead of a value
  • Convert an array:

    • Map (func): The result of calling func from each element and returning a new array
    • Sort (func): sort an array from small to large,func((a,b) => a-b)Otherwise, b-a modifies the array in place and returns the new modified array
    • Reserve (): Invert the array in place and return it
    • Split /join: the former converts a string to an array, the latter converts an array to a string and returns
    • Reduce (func,initial): Generally used for summation, by calling func for each element to calculate a single value on the array and passing intermediate results between calls
  • Iterative elements

    • ForEach (func): calls func forEach element and returns nothing
  • other

    • Array.isarray (arR): Checks whether the ARR is an Array
    • Arr.some (fn)/arr.every(fn): Calls the function fn on each element of an array similar to map. Return true if any/all results are true, false otherwise. Often used to check elements
    • Arr.fill (value,start,end): Repeatedly fill an array with value from start to end
    • Arr. copyWithin(target,start,end): will start the index at the tartget position and copy from start to end to itself for example:
      var fruits = ["Banana"."Orange"."Apple"."Mango"];
      fruits.copyWithin(2, 0);
      // fruits
      Banana,Orange,Banana,Orange
      Copy the code

Array to heavy

1. Use the ES6 Set to remove weights

function unique (arr) {
  return[... new Set (arr)] / / Array. The from (new Set (arr)]} var arr = [1, 1,'true'.'true'.true.true, 15, 15,false.false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a'.'a', {}, {}]; console.log(unique(arr)) //[1,"true".true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]
Copy the code

Regardless of compatibility, this de-weighting method has the least code. This method also fails to remove empty “{}” objects, and later higher-order methods add methods that remove repeated “{}”.

Why can’t I get rid of the “{}” object?

The reason is thatsetMethod comparisons compare key and value, with the former usedhashCode() the latter uses the equals() method ifsetObjects do not manually use equals() andhashThe Code(), key values are different, so the de-duplication cannot be recognizedCopy the code

2. Nest for with for, then splice to deduplicate (most commonly used in ES5)

Double loop, outer loop elements, inner loop when comparing values. If the values are the same, the value is deleted.

function unique(arr){            
        for(var i=0; i<arr.length; i++){
            for(var j=i+1; j<arr.length; j++){
                if(arr[I]===arr[j]){splice(j,1); j--; }}}returnarr; } var arr = [1,1, 1]'true'.'true'.true.true, 15, 15,false.false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a'.'a', {}, {}]; console.log(unique(arr)); / / [1,'true'.true, 15,false, undefined,null,NaN,NaN,'NaN', 0,'a', {}, {}]; //NaN and {} are not deduplicatedCopy the code

NaN and {} are not deduplicated

Why is NaN === NaN false

NaN means Not a Number, so a character that is Not a Number must Not be a character, but a range, a set. Just as A is not A number, B is not A number, but A is certainly not B. So NaN is actually not equal to itself.Copy the code

Why is {} === {} false

When comparing the size of two objects, the valueOf method of object is called, and if the result can be directly compared, the comparison result is returned. If the result cannot be directly compared in size, the toString method of object is called and the comparison result is returnedCopy the code

3. Use indexOf to de-weight

Create an empty result array, loop through the original array, determine whether the current element exists in the result array, if the same value is skipped, not the same value is pushed into the array.

Var arr = [1, 1,'true'.'true'.true.true, 15, 15,false.false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a'.'a', {}, {}];function unique(arr) {
  let newArr = [];
  for (let i = 0; i < arr.length; i++) {
    if(newArr.indexOf(arr[i]) === -1) {
      newArr.push(arr[i])
    }
  }
  returnnewArr } console.log(unique(arr)); / / [1,"true".true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {... }, {... }]Copy the code

NaN, {} is not deduplicated

4. Use the sort ()

function unique(arr) {
    arr = arr.sort()
    var arrry= [arr[0]];
    for (var i = 1; i < arr.length; i++) {
        if (arr[i] !== arr[i-1]) {
            arrry.push(arr[i]);
        }
    }
    returnarrry; } var arr = [1,1, 1]'true'.'true'.true.true, 15, 15,false.false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a'.'a', {}, {}]; console.log(unique(arr)) // [0, 1, 15,"NaN"NaN, NaN, {... }, {... },"a".false, null, true."true", undefined]      
Copy the code

NaN, {} is not deduplicated

5. Use includes

function unique(arr) {
    var array =[];
    for(var i = 0; i < arr.length; i++) {
            if(! Array.includes (arr[I])) {// Check whether the array has a value. }}returnArray} var arr = [1,1, 1]'true'.'true'.true.true, 15, 15,false.false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a'.'a', {}, {}]; console.log(unique(arr)) //[1,"true".true, 15, false, undefined, null, NaN, "NaN", 0, "a", {... }, {... }]Copy the code

{} no weight is removed

6. Using hasOwnProperty

The hasOwnProperty() method returns a Boolean value indicating whether the object itself has the specified property (that is, whether it has the specified key).

parameter

Prop: The name, or Symbol, of the String representation of the property to be tested.

The return value

Boolean value used to determine whether an object contains the specified property.

HasOwnProperty returns true as long as the property is present, even if the value of the property is null or undefined.

Use hasOwnProperty to determine whether an object property exists

function unique(arr) {
  var obj = {}
  return arr.filter(function(item,index,arr){
    return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)})} var arr = [1,1,'true'.'true'.true.true, 15, 15,false.false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a'.'a', {}, {}]; console.log(unique(arr)); / / [1,"true".true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}]
Copy the code

It’s all gone

7. Use the filter

function unique(arr) {
  return arr.filter(function(item,index,arr){
    returnarr.indexOf(item) === index; })} var arr = [1,1,'true'.'true'.true.true, 15, 15,false.false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a'.'a', {}, {}]; console.log(unique(arr)); / / [1,"true".true, 15, false, undefined, null, "NaN", 0, "a", {}, {}]
Copy the code

{} no weight is removed

8. Use the reduce + includes

function unique(arr) {
  returnarr.reduce((pre,cur) => pre.includes(cur) ? Pre: [.... The pre, cur], [])} var arr = [1, 1,'true'.'true'.true.true, 15, 15,false.false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a'.'a', {}, {}]; console.log(unique(arr)); / / [1,"true".true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]
Copy the code

Generate an array like [1-100]

When testing an array of large amounts of data, this can be generated:

const arr = new Array(100).fill(0).map((item,index) => index + 1) 
Copy the code

New Array(100) will generate an Array with 100 Spaces. This Array cannot be traversed by map(),filter(),reduce(),every(),some(), because the Spaces will be skipped. You can use […new Array(100)] to set the default value undefined to the space so that the Array can be traversed by the above methods

Array intersection

const a = [0, 1, 2, 3, 4, 5]
const b = [3, 4, 5, 6, 7, 8]
const duplicatedValues = [...new Set(a)].filter(item => b.includes(item))
duplicatedValues // [3, 4, 5]

Copy the code

The array takes the difference set

const a = [0, 1, 2, 3, 4, 5] const b = [3, 4, 5, 6, 7, 8] const diffValues = [...new Set([...a, ...b])].filter(item => ! b.includes(item) || ! a.includes(item)) // [0, 1, 2, 6, 7, 8]Copy the code

Array transfer object

Const arr = [1,2,3,4] const obj = {... arr} // {0: 1, 1: 2, 2: 3, 3: 4} const newObj = {0: 0, 1: 1, 2: 2, length: Const newArr= [...newObj] // Uncaught TypeError: Object is not iterable... // You can use array.form () to convert an array-like object into an Arraylet newArr = Array.from(newObj) // [0, 1, 2]

Copy the code

What is an iterable?

Subscript loops can be used to traverse arrays, but not maps and sets. To unify Set types, the ES6 standard introduces a new iterable type. Array, Map, and Set are all iterable types.

Collections of type iterable can be passed through the new for… Of loop to iterate.

for … The of loop is a new syntax introduced in ES6, so you can test whether your browser supports it:

'use strict';
var a = [1, 2, 3];
for (var x of a) {
}
console.log('Your browser supports for... of');
Copy the code

So for… Of loops and for… What’s the difference between in loops? for … The in loop, due to historical issues, actually iterates over the object’s property names. An Arrat array is actually an object, and the index of each of its elements is treated as an attribute.

When we manually add additional properties to the Array object, for… The in loop has an unexpected and unexpected effect:

var a = ['A'.'B'.'C'];
a.name = 'Hello';
for (var x in a) {
    console.log(x); // '0'.'1'.'2'.'name'
}
Copy the code

for … The in loop will include the name, but not the length property of the Array. for … The of loop fixes these problems completely, and only loops through the elements of the collection itself:

var a = ['A'.'B'.'C'];
a.name = 'Hello';
for (var x of a) {
    console.log(x); // 'A'.'B'.'C'
}
Copy the code

That’s why the new for… Of circulation

A better approach, however, is to use iterable’s built-in forEach method directly, which receives a function that is automatically called back after each iteration. Note that the forEach() method was introduced by the ES5.1 standard and you need to test whether the browser supports it.

Array. The from () method

Before we get to the array.from () method, let’s introduce array-like objects

  • Array-like objects: The most basic requirement for an array-like object is an object with a length attribute.

  • Array.from() : The array.from () method converts an array-like or traversable object into a real Array.

  • Array.from(object, mapFnc, thisValue) takes three arguments, array. from(object, mapFnc, thisValue), and the return value of this method is a new Array instance (a real Array).

    • Object: a pseudo-array object or iterable that is required to be converted into an array;
    • MapFnc: Optional, this callback is executed for each element in the new array
    • ThisValue: Optional, this object when the callback function mapFnc is executed
  • To convert an array-like object to a true array, the following conditions must be met:

    • The array object of this class must have the length property, which specifies the length of the array. If there is no length attribute, then the converted array is an empty array.
    • The attribute names of array objects of this class must be numeric or string arrays. The attribute names of array objects of this class may or may not be quoted.
  • You can convert the data that a Set deconstructs into an array

letArr =,2,3,4,5,6,7,8,9 [1]let set = new Set(arr)
console.log(Array.from(set)) / /,2,3,4,5,6,7,8,9 [1]Copy the code

Arrays are often traversed

Array traversal has forEach, every, some, filter, map, reduce, reduceRight, find, findIndex and other methods, many methods can achieve the same effect. Array methods should not only be used, but used well. To use it well, you need to know when and how.

Mixed use of traversal

The filter and map methods still return an array, so you can mix them with other array traversal methods. Note that more traversals are less efficient

const arr = [1, 2, 3, 4, 5] const value = arr .map(item => item * 3) // [3, 6, 9, 12, 15] .filter(item => item % 2 === 0) // [6, 12] .map(item => item + 1) // [7, 13] .reduce((prev, curr) => prev + curr, 0) // [20] console.log(value); / / 20Copy the code

Check whether all elements of the array meet the criteria

const arr = [1, 2, 3, 4, 5]
const isAllNum = arr.every(item => typeof item === 'number')
console.log(isAllNum); // true

Copy the code

Checks whether any elements in the array match the criteria

const arr = [1, 2, 3, 4, 5]
const hasNum = arr.every(item => typeof item === 'number')
console.log(hasNum); // true

Copy the code

Find the first element/subscript that meets the criteria

const arr = [1, 2, 3, 4, 5] const findItem = arr.find(item => item === 3) const findIndex = arr.findIndex(item => item === 3) // Returns the subscript 2 of the subitemCopy the code

Array error

There are many ways to use an array, many of which can achieve the same effect, so use the appropriate method depending on your needs.

A big cause of junk code is the misuse of common array methods. Here are some things to note:

Array. Includes () and array. IndexOf ()

Array.includes () returns a Boolean value, and array.indexof () returns the indexOf the array’s children. IndexOf must be used in cases where an index value is required.

Note: Array.indexof () cannot find NaN, return -1, array.includes() can find NaN, return true~

[NaN].includes(NaN) // true
[NaN].indexOf(NaN) // -1
Copy the code

Array. The find () and array. The filter ()

Array.filter () returns an array of all eligible subitems and iterates through all arrays; Array.find (), on the other hand, only returns the first qualifying subitem, which is a short-circuit operation