JS array method review 2

A programmer who doesn’t use an array well is not a good one, I said~

I took over a project some time ago. The logic was obscure and the code was huge and redundant, making it extremely difficult to get started. The big reason is that the array method is not proficient, which leads to a lot of garbage code. In fact, many places can become simple, efficient and elegant with a little modification. Therefore, I will summarize here the common methods of arrays and KitKat's kinky skills (KitKat's kinky skills are mainly reduce~).

Array operations must first be noted and remember splice、sort、reversethat these three common methods are operations on the array itself, which will change the array itself. Other methods that will change itself are additions push/pop/unshift/shift, deletions , filling, filland duplication and filling copyWithin.

Let's talk about the common methods of arrays first, and then talk about the misunderstanding of using them.

Array common methods

First present an array method lazy figure to sacrifice to the sky! (Except for the Array.keys()/Array.values()/Array.entries()basics):

Encyclopedia of Array Methods

Generate an array like [1-100]:

When testing a large amount of array data, you can:

  •  
let arr = new Array(100).fill(0).map((item, index) => index + 1)

Array destructuring assignment application

  •  
// 交换变量[a, b] = [b, a][o.a, o.b] = [o.b, o.a]// 生成剩余数组const [a, ...rest] = [...'asdf'] // a:'a',rest: ["s", "d", "f"]

Shallow copy of array

  •  
const arr = [1, 2, 3]const arrClone = [...arr]// 对象也可以这样浅拷贝const obj = { a: 1 }const objClone = { ...obj }

There are many shallow copy methods arr.slice(0, arr.length)/Arror.from(arr), but ...after using the operator, you won't want to use others~

Array merge

  •  
const arr1 = [1, 2, 3]const arr2 = [4, 5, 6]const arr3 = [7, 8, 9]const arr = [...arr1, ...arr2, ...arr3]

arr1.concat(arr2, arr3)It can also be merged, but ...after using the operator, you won't want to use other ones~

Array deduplication

  •  
const arr = [1, 1, 2, 2, 3, 4, 5, 5]const newArr = [...new Set(arr)]

new Set(arr)Accepts an array parameter and generates a set structure data type. Elements of the set data type will not be repeated and yes Array Iterator, so you can use this feature to remove duplication .

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]

Array subtraction

  •  
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]

Array to object

  •  
const arr = [1, 2, 3, 4]const newObj = {...arr} // {0: 1, 1: 2, 2: 3, 3: 4}const obj = {0: 0, 1: 1, 2: 2, length 3}// 对象转数组不能用展开操作符,因为展开操作符必须用在可迭代对象上let newArr = [...obj] // Uncaught TypeError: object is not iterable...// 可以使用Array.form()将类数组对象转为数组let newArr = Array.from(obj) // [0, 1, 2]

Array common traversal

Arrays are commonly traversed and there are  forEach、every、some、filter、map、reduce、reduceRight、find、findIndex other methods, and many methods can achieve the same effect. The array method must not only be used, but also be used well. To use it well, you need to know when and what method to use.

Mixed use of traversal

filterThe mapreturn value of the method is still an array, so it can be mixed with other array traversal methods. Note that the more traversal, the lower the efficiency~

const arr = [1, 2, 3, 4, 5]const value = arr    .map(item => item * 3)    .filter(item => item % 2 === 0)    .map(item => item + 1)    .reduce((prev, curr) => prev + curr, 0)

Check whether all elements of the array meet the judgment conditions

  •  
const arr = [1, 2, 3, 4, 5]const isAllNum = arr.every(item => typeof item === 'number')

Check whether any element of the array meets the judgment condition

  •  
const arr = [1, 2, 3, 4, 5]const hasNum = arr.some(item => typeof item === 'number')

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) // 返回子项的下标

Misunderstanding of Array Usage

There are many methods for arrays, and many methods can achieve the same effect, so use the appropriate method according to your needs.

A major cause of garbage code is improper use of common methods of arrays. Here are some points to note:

array.includes() 和 array.indexOf()

array.includes() Returns a boolean value, array.indexOf() returns the index of an array item. indexOf Be sure to use it when an index value is required.

  •  
const arr = [1, 2, 3, 4, 5]
// 使用indexOf,需要用到索引值const index = arr.indexOf(1) // 0if (~index) { // 若index === -1,~index得到0,判断不成立;若index不为-1,则~index得到非0,判断成立。    arr.spilce(index, 1)}
// 使用includes,不需要用到索引值// 此时若用indexOf会造成上下文上的阅读负担:到底其他地方有没有用到这个index?const isExist = arr.includes(6) // trueif (!isExist) {
   
       arr.push(6)}

array.find() 、 array.findIndex() 和 array.some()

array.find()The return value is the first eligible array item, the index of the first eligible array item is array.findIndex() returned, and the item with array.some() or without compound conditions is returned true, if there is any return , if there is no return false. Note that these three are all short-circuit operations, that is, the traversal will not continue after finding the qualified one.

It is used when the sub-items of the array is array.find() needed; when the index value of the sub-item  array.findIndex() is needed; and if only the sub-items that meet the conditions need to be known, it is used  array.some().

  •  
const arr = [{label: '男', value: 0}, {label: '女', value: 1}, {label: '不男不女', value: 2}]
// 使用someconst isExist = arr.some(item => item.value === 2)if (isExist) {
   
       console.log('哈哈哈找到了')}
// 使用findconst item = arr.find(item => item.value === 2)if (item) {
   
       console.log(item.label)}
// 使用findIndexconst index = arr.findIndex(item => item.value === 2)if (~index) {
   
       const delItem = arr[index]    arr.splice(index, 1)    console.log(`你删除了${delItem.label}`)}

It is recommended to use when only Boolean values ​​are needed and when the array items are strings or numbers  array.some():

  •  
// 当子包含数字0的时候可能出错const arr = [0, 1, 2, 3, 4]
// 正确const isExist = arr.some(item => item === 0)if (isExist) {
   
       console.log('存在要找的子项,很舒服~')}
// 错误const isExist = arr.find(item => item === 0)if (isExist) { // isExist此时是0,隐式转换为布尔值后是false    console.log('执行不到这里~')}

// 当子项包含空字符串的时候也可能出错const arr = ['', 'asdf', 'qwer', '...']
// 正确const isExist = arr.some(item => item === '')if (isExist) {
   
       console.log('存在要找的子项,很舒服~')}
// 错误const isExist = arr.find(item => item === '')if (isExist) { // isExist此时是'',隐式转换为布尔值后是false    console.log('执行不到这里~')}

array.find() 和 array.filter()

Just know that what is  array.filter() returned is an array composed of all eligible sub-items, and all arrays will be traversed; and  array.find() only the first eligible sub-item is returned, which is a short-circuit operation. No more examples~

Reasonable use of Set data structure

Because es6 natively provides a  Set data structure, it  Set can ensure that the sub-items are not repeated, and it is very convenient to convert with the array, so in some scenarios that may involve repeated addition, it can be directly used  Set instead  Array, avoiding multiple places to repeatedly determine whether the existing Child.

  •  
const set = new Set()set.add(1)set.add(1)set.add(1)set.size // 1const arr = [...set] // arr: [1]

Powerful reduce

array.reduce Traverse and use the return value of the current callback function as the first parameter of the next callback function execution.

Using to  array.reduce replace some scenes that need to be traversed multiple times can improve the efficiency of code operation.

Suppose there is an array composed of the letter's' plus a number for each element as follows arr, and now find the largest number in it: ( arrnot empty)

  •  
const arr = ['s0', 's4', 's1', 's2', 's8', 's3']
// 方法1  进行了多次遍历,低效const newArr = arr.map(item => item.substring(1)).map(item => Number(item))const maxS = Math.max(...newArr)
// 方法2  一次遍历const maxS = arr.reduce((prev, cur) => {
   
     const curIndex = Number(cur.replace('s', ''))  return curIndex > prev ? curIndex : prev}, 0)
  •  
const arr = [1, 2, 3, 4, 5]
 // 方法1  遍历了两次,效率低const value = arr.filter(item => item % 2 === 0).map(item => ({ value: item }))
// 方法1  一次遍历,效率高const value = arr.reduce((prev, curr) => {
   
       return curr % 2 === 0 ? [...prev, curr] : prev}, [])

You can also use reduce to do the following processing to generate the desired html structure:

  •  
// 后端返回数据const data = {
   
     'if _ then s9': [    '作用属于各种,结构属于住宅,结构能承受作用,作用属于在正常建造和正常使用过程中可能发生',    '作用属于各种,结构属于住宅,结构能承受作用,作用属于在正常建造和正常使用过程中可能发生',    '作用属于各种,结构属于住宅,结构能承受作用,作用属于在正常建造和正常使用过程中可能发生'    ],  'if C then s4': [    '当有条件时时,结构构件满足要求,要求属于安全性、适用性和耐久性',    '当有条件时时,住宅结构满足要求,要求属于安全性、适用性和耐久性'  ]}
const ifthens = Object.entries(data).reduce((prev, cur) => {
   
     const values = cur[1].reduce((prev, cur) => `${prev}<p>${cur}</p>`, '')  return `    ${prev}    <li>      <p>${cur[0]}</p>      ${values}    </li>  `}, '')
const html = `  <ul class="nlp-notify-body">    ${ifthens}  </ul>`

The generated html structure is as follows:

  •  
<ul class="nlp-notify-body">              <li>    <p>if _ then s9</p>    <p>作用属于各种,结构属于住宅,结构能承受作用,作用属于在正常建造和正常使用过程中可能发生</p>    <p>作用属于各种,结构属于住宅,结构能承受作用,作用属于在正常建造和正常使用过程中可能发生</p>    <p>作用属于各种,结构属于住宅,结构能承受作用,作用属于在正常建造和正常使用过程中可能发生</p>  </li>  <li>    <p>if C then s4</p>    <p>当有条件时时,结构构件满足要求,要求属于安全性、适用性和耐久性</p>    <p>当有条件时时,住宅结构满足要求,要求属于安全性、适用性和耐久性</p>  </li></ul>

Guess you like

Origin blog.csdn.net/AN0692/article/details/109993210
Recommended