数组操作与应用(very important)

这是我第11篇简书。

一、操作

(一)Array.find/ Array.findIndex

  • find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined
  • findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1
 1.val是特定值
  let obj = {}
  obj = this.province.find(item => {
    return item.value === val
  })

 2.传入一个回调函数,找到数组中符合当前搜索规则的第一个元素,返回它,并且终止搜索。
  const arr = [1, "2", 3, 3, "2"]
  console.log(arr.find(n => typeof n === "number")) // 1

(二)Array.filter

用于筛选数组中满足条件的元素,返回一个筛选后的新数组

  过滤两个数组中相同的项
 var a = [1, 2, 3, 4]
 var b = [2, 3, 5]
// 筛选a中不包含b的元素的元素,返回新数组
a.filter(item => b.indexOf(item) === -1)  // [1, 
[1, 2, 3].filter(item => {return item > 2}) //[3]

(三)slice()和splice()

1、slice(start,end):方法可从已有数组中返回选定的元素,返回一个新数组,包含从start到end(不包含该元素)的数组元素(返回的新数组包含start,不包含end)。

  • start参数:必须,规定从何处开始选取,如果为负数,规定从数组尾部算起的位置,-1是指最后一个元素。
  • end参数:可选(如果该参数没有指定,那么切分的数组包含从start倒数组结束的所有元素,如果这个参数为负数,那么规定是从数组尾部开始算起的元素)。

注意:该方法不会改变原数组,而是返回一个子数组,如果想删除数组中的一段元素,应该使用Array.splice()方法。

var arr = [1,2,3,4,5];
arr.slice(0,3); // [1,2,3]
arr.slice(1,3); // [2,3]
arr.slice(2); // [3,4,5]

2、splice():该方法向或者从数组中添加或者删除项目,返回被删除的项目。(该方法会改变原数组)
splice(index,howmany,item1,...itemX)

  • index参数:必须,整数,规定添加或者删除的位置,使用负数,从数组尾部规定位置。
  • howmany参数:必须,要删除的数量,如果为0,则不删除项目。
  • tem1,...itemX参数:可选,向数组添加的新项目。
var arr = [1,2,3,4,5];
console.log(arr.splice(2,1,"hello")); // [3]  返回的新数组
console.log(arr); // [1, 2, "hello", 4, 5]  改变了原数组

console.log(arr.splice(1,2)); // [2,3] 
console.log(arr); // [1, 4, 5] 

(四)Array.from()

Array.from() 可以将类数组对象可遍历对象(包括ES6新增的数据结构 Set 和 Map)转化为真正的数组。

从 String 生成数组:

Array.from('foo'); 
// [ "f", "o", "o" ]

从类数组对象(arguments)生成数组:

function fn() {
  return Array.from(arguments);
}

fn(1, 2, 3);

// [ 1, 2, 3 ]

从 Set 生成数组:

set用来定义不重复数组的数据类型(es6)
const set = new Set(['foo', 'bar', 'baz', 'foo']);
Array.from(set);
// [ "foo", "bar", "baz" ]

从 Map 生成数组:

const map = new Map([[1, 2], [2, 4], [4, 8]]);
Array.from(map);
// [[1, 2], [2, 4], [4, 8]]

const mapper = new Map([['1', 'a'], ['2', 'b']]);
Array.from(mapper.values());
// ['a', 'b'];

Array.from(mapper.keys());
// ['1', '2'];

在 Array.from 中使用箭头函数:

Array.from([1, 2, 3], x => x + x);
// [2, 4, 6]

Array.from({length: 5}, (v, i) => i);
// [0, 1, 2, 3, 4]

数组去重合并:

function combine(){ 
    let arr = [].concat.apply([], arguments);  //没有去重复的新数组 
    return Array.from(new Set(arr));
} 

var m = [1, 2, 2], n = [2,3,3]; 
console.log(combine(m,n));    // [1, 2, 3]

(五)map()

用于遍历数组,返回处理之后的新数组

arr = data.map(item => ({
      id: item.id,
      name: item.departmentName,
      departmentId: item.departmentId,
      corpid: item.corpid,
      isLeaf: !item.isleaf
  }))
arr.map(item => item * 2)
1.将string数组转换为number数组 
 
let x1 = ['1','2'];
console.log(x1);
//["1", "2"]
 
x1 = x1.map(Number);
console.log(x1);
//[1,2]

2.将number数组转换为string数组 
 
let x2 = [1,2];
console.log(x2);
//[1, 2]
 
x2 = x2.map(String);
console.log(x2);
//['1','2']

(六)reduce方法

reduce()方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
reduce()可以作为一个高阶函数,用于函数的 compose

注意: reduce()对于空数组是不会执行回调函数的。

语法:

arr.reduce(function(prev,cur,index,arr){

}, initialValue);

arr 表示原数组;
prev 表示上一次调用回调时的返回值,或者初始值 initialValue;
cur 表示当前正在处理的数组元素;
index 表示当前正在处理的数组元素的索引,若提供 initialValue 值,则索引为0,否则索引为1;
initialValue 可选。传递给函数的初始值。可选0,也可选[]
// 求和
const arr = [1, 2, 3, 4, 5] 
const sum = arr.reduce((pre, item) => { 
    return pre + item 
  }, 0)  // 从数组第1项开始
console.log(sum) // 15

注:reduceRight()
该方法用法与reduce()其实是相同的,只是遍历的顺序相反,它是从数组的最后一项开始,向前遍历到第一项。

(七)forEach()

用于遍历数组,无返回值。

// 一般第数组处理
dataList.forEach(item => {
   arr.push(item)
})

// 加入筛选条件
datagroup.forEach(item => {
 if (item.modelType === 2) {
   personIds.push(item.id)
 }
 if (item.modelType === 1) {
   departmentIds.push(item.departmentId)
 }
})

//
data.forEach(item => {
 let obj = {
     ...item,
     name: item.departmentName,
     id: item.departmentId
   }
   arr.push(obj)
   this.dataObj[item.departmentId] = obj
})

(八)every()

用于判断数组中的每一项元素是否都满足条件,返回一个布尔值。

var isEvery = arr.every(function(item,index,array){
    return item > 0;
});
console.log(isEvery);

 // 是否更新全选
updateCheckAll(list) {
  this.isCheckAll = list.every(item => item.checkeds)
}

(九)some()

用于判断数组中的是否存在满足条件的元素,返回一个布尔值。

let parendId = this.data.parentId
let isExist = this.parentDepartments.some(({ departmentId }) => {
    return parseInt(departmentId) === parseInt(parendId)
})
item.isFullSelected = this.parentDepartments.some(
    pd => pd.departmentId === item.departmentId
)

(10)补充

以上forEach()、map()、every()、some()和filter()等除了传递一个匿名函数作为参数之外,还可以传第二个参数,该参数用于指定匿名函数内的this指向。

// 传两个参数
arr.forEach(function(item,index,array){
    console.log(this);  // 指向arr
},arr);

// 只传一个匿名函数的话,则this指向window
arr.forEach(function(item,index,array){
    console.log(this);  // window
});

二、数组的应用

1、数组去重

普通方法:

Array.prototype.distinct = function() {
  var arr = this,
    result = [],
    i,
    j,
    len = arr.length;
  for (i = 0; i < len; i++) {
    for (j = i+1; j < len; j++) {
      if (arr[i] === arr[j]) {
        j = ++i;
      }
    } 
    result.push(arr[i]);
  }
  return result;
}

[1, 2, 3, 3, 4, 4].distinct();  // [1, 2, 3, 4]

reduce方法:

var new Arr = [1, 2, 3, 3, 4, 4].reduce(function (prev, cur) {
  prev.indexOf(cur) === -1 && prev.push(cur);
}). [])

建议(骚)方法:

set用来定义不重复数组的数据类型
  [...new Set([1, 2, 3, 3, 4, 4])]   // [1, 2, 3, 4]
Array.from(new Set([1, 2, 3, 3, 4, 4]))  // [1, 2, 3, 4]

2、排序

内置方法:

升序: [2, 1, 3, 4].sort((a, b) => a - b);  // [1, 2, 3, 4]
降序: [1, 2, 3, 4].sort((a, b) => b - a);  // [4, 3, 2, 1]

冒泡排序:

升序:
Array.prototype.bubleSort = function() {
  let arr = this,
    len = arr.length;
  for (let outer = len; outer >= 2 ; outer--) {
    for (let inner = 0; inner <= outer - 1; inner++) {
      if (arr[inner] > arr[inner+1]) {
        [arr[inner], arr[inner + 1]] = [arr[inner + 1], arr[inner]]
      }
    }
  }
  return arr;
}
[3, 4, 2, 1].bubleSort();  // [1, 2, 3, 4]

选择排序:

Array.prototype.selectSort = function() {
  let arr = this,
    len = arr.length,
    i,
    j;
  for (i = 0; i < len; i++) {
    for (j = i; j < len; j++) {
      if (arr[i]) > arr[j]) {
        [arr[i], arr[j]] = [arr[j], arr[i]];
      }
    }
  }
  return arr;
}
[3, 4, 2, 1].selectSort();  // [1, 2, 3, 4]

3、最大值

Math.max(...[1, 2, 3, 4]) // 4
Math.max.apply(this, [1, 2, 3, 4]) // 4
[1, 2, 3, 4].reduce( (prev, cur, curIndex, arr) => {
  return Math.max(prev, cur);
}, 0)

4、求和

利用eval()函数:

  • eval()函数会将传入的字符串当做 JavaScript 代码进行执行。
    eval("2+3") // 5
eval([1,2,3,4].join('+'))  // 10

利用reduce()方法:

[1,2,3,4].arr.reduce((prev, cur) => prev + cur) //10

5、合并

[1,2,3,4].concat([5,6]) //[1,2,3,4,5,6]
[...[1,2,3,4],...[4,5]] //[1,2,3,4,5,6]
[1,2,3,4].push.apply([1,2,3,4],[5,6]) //[1,2,3,4,5,6]

6、判断是否包含某值

[1,2,3].includes(4) //false
[1,2,3].indexOf(4) //-1 如果存在换回索引
[1, 2, 3].find((item) => item===3 )) //3 如果数组中无值返回undefined
[1, 2, 3].findIndex((item) => item === 3)) //2 如果数组中无值返回-1
[1,2,3].some(item => { return item===3 }) // true

7、扁平化n维数组

(1)利用递归和数组合并方法concat实现扁平:

function flatten(arr) {
    while(arr.some(item=>Array.isArray(item))) {
        arr = [].concat(...arr);
    }
    return arr;
}
flatten([1,[2,3]]) //[1,2,3]
flatten([1,[2,3,[4,5]]) //[1,2,3,4,5]

(2)利用ES10新api——Array.flat(n)
Array.flat(n)ES10扁平数组的api,n表示数组嵌套的深度,如果数组嵌套两层,n取值大于或等于1都可以,n值为Infinity时维度为无限大。

[1,[2,3]].flat(1) //[1,2,3]
[1,[2,3,[4,5]].flat(1) //[1,2,3,4,5]
[1[2,3,[4,5[...]].flat(Infinity) //[1,2,3,4...n]

8、对象和数组转化

Object.keys({name:'张三',age:14})  //['name','age']
Object.values({name:'张三',age:14})  //['张三',14]
Object.entries({name:'张三',age:14})  //[[name,'张三'],[age,14]]

9、数组第每一项设置值

[1,2,3].map(() => 0)  // [0, 0, 0]

[1,2,3].map(() => '')   // ["", "", ""]

fill():

[1,2,3].fill(false)  // [false,false,false]
注:fill填充对象会报错
禁止转载,如需转载请通过简信或评论联系作者。

推荐阅读更多精彩内容