JavaScript - 数组方法

109 阅读6分钟

1、创建空数组 & new Array( ... )

// new Array( Number ):返回长度为 `N 稀疏数组`
const arr = new Array(5);
console.log(arr); // [empty * 5]
console.log(arr.length); // 5


// new Array( ele0, ele1[, ...[, eleN]] ):返回 [ ele0, ele1...]
const arr = new Array("a", "b", "c");
console.log(arr); // ["a", "b", "c"]
console.log(arr.length); // 3

2、创建数组 & of、from

// 1、of:创建一个具有可变数量参数的新数组实例
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
new Array(7); // [ , , , , , , ]
new Array(1, 2, 3); // [1, 2, 3]


// 2、from:将`可迭代对象`转换为一个数组
// 从 string 生成数组
Array.from('foo'); // [ "f", "o", "o" ]

// 从 set 生成数组
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]]

// 从 arguments 生成数组
function f() { 
    return Array.from(arguments); 
} 
f(1, 2, 3); // [ 1, 2, 3 ]

3、判断数据 & isArray

Array.isArray([1, 2, 3]);
// true
Array.isArray({ foo: 123 });
// false
Array.isArray("foobar");
// false
Array.isArray(undefined);
// false

4、遍历 & forEach、map、reduce、filter、every、some

// 1、forEach
// 对数组的每个元素执行一次给定的函数
// 跳过已被删除或未初始化 item 的稀疏数组


// 2、map
// 返回一个新数组
// 跳过已被删除或未初始化 item 的稀疏数组
var numbers = [1, 4, 9];
var doubles = numbers.map(function (num) {
  return num * 2;
});
// doubles数组的值为: [2, 8, 18]
// numbers数组未被修改: [1, 4, 9]


// 3、reduce( reduceRight )
// 返回一个新的处理后的集合
-   参数一:callback
    -   accumulator:累计器累计回调的返回值;
    -   currentValue:数组中正在处理的元素
    -   index:数组中正在处理的当前元素的索引
    -   array:调用reduce()的数组
-   参数二:initialValue
    -   作为第一次调用 callback函数时的第一个参数的值
    -    如果没有提供初始值,则将使用数组中的第一个元素
    
    
// 4、reduce( reduceRight )
// 返回一个满足条件的新数组
// 跳过已被删除或未初始化 item 的稀疏数组
const words = ["spray", "limit", "exuberant"];
const result = words.filter((word) => word.length > 6);
console.log(result);
//["exuberant"]


// 5、every
// 返回一个布尔值、所有元素同时满足条件时返回 true 
// 跳过已被删除或未初始化 item 的稀疏数组
[12, 5, 8, 130, 44].every((x) => x >= 10); // false

[12, 54, 18, 130, 44].every((x) => x >= 10); // true


// 6、some
// 返回一个布尔值、某个元素满足条件时返回 true 
// 跳过已被删除或未初始化 item 的稀疏数组
function isBiggerThan10(element, index, array) {
  return element > 10;
}

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


5、查找 & includes、indexOf、find(可稀疏)、findIndex(可稀疏)

// 1、includes
-   判断一个数组是否包含一个指定的值
-   包含则返回 true,否则返回false
const pets = ['cat', 'dog', 'bat'];
console.log(pets.includes('cat'));
// true
console.log(pets.includes('at'));
// false


// 2、indexOf ( lastIndexOf )
-   数组中可以找到一个给定元素的第一个索引
-   不存在,则返回-1
var array = [2, 5, 9];
array.indexOf(2); // 0
array.indexOf(7); // -1
array.indexOf(9, 2); // 2
array.indexOf(2, -1); // -1
array.indexOf(2, -3); // 0


// 3、find
-   返回数组中 满足条件的第一个元素的值
-   否则返回 undefined
const array1 = [5, 12, 8, 130, 44];
const found = array1.find((element) => element > 10);
console.log(found); // 12


// 4、findIndex
-   返回数组中 满足条件第一个元素的索引
-   若没有找到对应元素则返回-1
const array1 = [5, 12, 8, 130, 44];
const isLargeNumber = (element) => element > 13;
console.log(array1.findIndex(isLargeNumber)); // 3


6、改原数组 & 7 + copyWithin、fill(可稀疏)

// 1、pop
// 删除最后一个元素
// 并返回该元素的值


// 2、push
// 将一个或多个元素添加到数组的末尾
// 并返回该数组的新长度


// 3、shift
// 从数组中删除第一个元素
// 并返回该元素的值


// 4、unshift
// 将一个或多个元素添加到数组的开头
// 返回该数组的新长度


// 5、reverse
// 将数组中元素的位置颠倒
// 并返回该数组
const array1 = ["one", "two", "three"];
const reversed = array1.reverse();
console.log("array1:", array1); //["three", "two", "one"]
console.log("reversed:", reversed); //["three", "two", "one"]


// 6、sort
// 对数组的元素进行排序
// 默认排序顺序是在将元素转换为字符串

const months = ["March", "Jan", "Feb", "Dec"];
months.sort(); // ["Dec", "Feb", "Jan", "March"]
const array1 = [1, 30, 4, 21, 100000];
array1.sort(); // [1, 100000, 21, 30, 4]


// 7、splice
// 通过删除或替换现有元素或者原地添加新的元素来修改数组
// 语法:array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
// start:指定修改的开始位置(从0计数)
// deleteCount :表示要移除的数组元素的个数
// item1, item2, ... 可选:要添加进数组的元素
const months = ["Jan", "March", "April", "June"];
months.splice(1, 0, "Feb");
console.log(months); // ["Jan", "Feb", "March", "April", "June"]
months.splice(4, 1, "May");
console.log(months); // ["Jan", "Feb", "March", "April", "May"]


// 8、copyWithin
// 浅复制数组的一部分到同一数组中的另一个位置
// 不会改变原数组的长度,只改变原数组的值
// 语法:arr.copyWithin(target[, start[, end]])
// target:复制序列到该位置
// start:复制元素的起始位置,默认为 0
// end:复制元素的结束位置,默认到数组的尾部
const array1 = ["a", "b", "c", "d", "e"];
array1.copyWithin(0, 3, 4);
console.log(array1); // ["d", "b", "c", "d", "e"]


// 9、fill
// 用一个固定值填充一个数组中从起始索引到终止索引内的全部元素
// 语法:arr.fill(value[, start[, end]])
// value:要填充的数值
// start:起始索引,默认值为0。
// end:终止索引,默认值为 this.length。
const array1 = [1, 2, 3, 4];
array1.fill(0, 2, 4);
console.log(array1); //[1, 2, 0, 0]

7、其他方法 & slice、concat、join

// 1、slice
// 返回一个新的数组对象
// 一个由 begin 和 end 决定的原数组的 浅拷贝
const animals = ["ant", "bison", "camel", "duck", "elephant"];
animals.slice(2); // ["camel", "duck", "elephant"]


// 2、concat
// 合并两个数组
var alpha = ["a", "b", "c"];
var numeric = [1, 2, 3];
let newArr = alpha.concat(numeric);
// newArr ['a', 'b', 'c', 1, 2, 3]

// 合并数组和原始值
var alpha = ["a", "b", "c"];
var alphaNumeric = alpha.concat(1, [2, 3]);
// results in ['a', 'b', 'c', 1, 2, 3]
console.log(alphaNumeric);

// 合并嵌套数组
var num1 = [[1]];
var num2 = [2, [3]];
var num3 = [5, [6]];
var nums = num1.concat(num2);
console.log(nums); //[[1], 2, [3]]
var nums2 = num1.concat(4, num3);
console.log(nums2); //[[1], 4, 5,[6]]


// 3、join
const elements = ["Fire", "Air", "Water"];
console.log(elements.join());
// "Fire,Air,Water"
console.log(elements.join(""));
// "FireAirWater"
console.log(elements.join("-"));
// "Fire-Air-Water"

8、常用方法的源码实现

// 1、forEach方法
// 循环中做操作item,无返回值
Array.prototype.myForeEach = function (cb) {
  var _arr = this; // 数组本身
  var _len = _arr.length; // 数组长度
  var _arg2 = arguments[1] || window; // 第二个this指向的参数

  for (var i = 0; i < _len; i++) {
    // [_arr[i]:当前值 i:当前索引 _arr:原数组
    cb.apply(_arg2, [_arr[i], i, _arr]);
  }
};

// 2、map方法:映射
// 操作每一项,返回新的数组( 需要做深拷贝)
Array.prototype.myMap = function (cb) {
  var _arr = this;
  var _len = _arr.length;
  var _arg2 = arguments[1] || window;

  var _newArr = [];
  var _item;

  for (var i = 0; i < _len; i++) {
    // 由于要返回新的值,需要对item做深拷贝
    _item = deepClone(_arr[i]);
    _newArr.push(cb.apply(_arg2, [_item, i, _arr]));
  }

  // 返回新的数组
  return _newArr;
};

// 3、reduce方法:归纳
// 有一个item满足条件返回true,否则为false
Array.prototype.myReduce = function (cb, initialValue) {
  var _arr = this;
  var _len = _arr.length;
  var _arg3 = arguments[2] || window;

  var _item;
  for (var i = 0; i < _len; i++) {
    _item = deepClone(_arr[i]);
    initialValue = cb.apply(_arg3, [initialValue, _item, i, _arr]);
  }
  return initialValue;
};

// 4、filter方法:过滤
// 返回符合条件的item,返回新的数组( 需要做深拷贝)
Array.prototype.myFilter = function (cb) {
  var _arr = this;
  var _len = _arr.length;
  var _arg2 = arguments[1] || window;

  var _newArr = [];
  var _item;
  for (var i = 0; i < _len; i++) {
    _item = deepClone(_arr[i]);
    cb.apply(_arg2, [_item, i, _arr]) && _newArr.push(_item);
  }

  // 返回新的数组
  return _newArr;
};

// 5、every方法
// 所有item都满足条件返回true,否则为false
Array.prototype.myEvery = function (cb) {
  var _arr = this;
  var _len = _arr.length;
  var _arg2 = arguments[1] || window;

  var _res = true;
  for (var i = 0; i < _len; i++) {
    // 判断函数的调用结果
    if (!cb.apply(_arg2, [_arr[i], i, _arr])) {
      _res = false;
      break;
    }
  }
  return _res;
};

// 6、some方法
// 有一个item满足条件返回true,否则为false
Array.prototype.mySome = function (cb) {
  var _arr = this;
  var _len = _arr.length;
  // 手动传递this的绑定对象,默认为window
  var _arg2 = arguments[1] || window;
  var _res = false;
  for (var i = 0; i < _len; i++) {
    if (cb.apply(_arg2, [_arr[i], i, _arr])) {
      _res = true;
      break;
    }
  }
  return _res;
};

// 7、reduceRight方法:归纳
// 有一个item满足条件返回true,否则为false
Array.prototype.myReduceRight = function (cb, initialValue) {
  var _arr = this;
  var _len = _arr.length;
  var _arg3 = arguments[2] || window;
  var _item;
  for (var i = _len - 1; i >= 0; i--) {
    _item = deepClone(_arr[i]);
    initialValue = cb.apply(_arg3, [initialValue, _item, i, _arr]);
  }
  return initialValue;
};