Array的方法简单整理
[[toc]]
快速生成一个数组
 Array.from(Array(100), (key, index) => index);
  [...new Array(100).keys()]
   Array(3).fill(''); 
  new Array(10).fill({}).map((item)=>{  return {     title:"掘金会员",     createtime:"2020-05-03",     state:1,     price:19.8,     timeNum:12,     userName:"虎克小哥哥",     age:18,     city:"上海"   } })
 
  let arr = []; (function dfs(i) {   if (i < 100) {     arr.push(i);     dfs(++i);   } }(0));
  Array(100).join(",").split(",").map((key,index)=> index)
  Array.apply(null,Array(100)).map((key,index)=>index)
 
  | 
 
some() & every()
every()与some()方法都是JS中数组的迭代方法。
some()是对数组中每一项运行给定函数,如果该函数对任一项返回true,则返回true;some一直在找符合条件的值,一旦找到,则不会继续迭代下去。
every()是对数组中每一项运行给定函数,如果该函数对每一项返回true,则返回true;every从迭代开始,一旦有一个不符合条件,则不会继续迭代下去。
reduce()
arr.reduce(function(Accumulator,CurrentValue,CurrentIndex,SourceArray){ ... }, init);
  | 
 
var arr = [3,9,4,3,6,0,9];
 
  var sum = arr.reduce(function (prev, cur) {     return prev + cur; },0);
 
  var max = arr.reduce(function (prev, cur) {     return Math.max(prev,cur); });
  Math.max(...arr);
 
  var newArr = arr.reduce(function (prev, cur) {     prev.indexOf(cur) === -1 && prev.push(cur);     return prev; },[]);
   | 
 
isArray()
Array.isArray() 用于确定传递的值是否是一个 Array。
Array.isArray([1, 2, 3]);  
  Array.isArray({foo: 123});  
 
  let dom1 =  document.getElementsByClassName('token') Array.isArray(dom1);   Array.isArray([...dom1]);   Array.isArray(Array.from(dom1));  
   | 
 
Array.isArray 实现
Array.myIsArray = function(o) {   return Object.prototype.toString.call(Object(o)) === '[object Array]'; };
  console.log(Array.myIsArray([])); 
  | 
 
slice()
请注意: 该方法并不会修改数组,而是返回一个子数组。如果想删除数组中的一段元素,应该使用方法 Array.splice()。
- arr.slice(begin ,end?)
- (包含 begin,但不包含 end)。
 
- slice(1,4) 会提取原数组中从第二个元素开始一直到第四个元素的所有元素 (索引为 1, 2, 3的元素)。
 
 
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
 
  console.log(animals.slice(2));
 
  console.log(animals.slice(2, 4));
 
  console.log(animals.slice(1, 5));
 
   | 
 
 Array.prototype.slice = function(start,end){      var result = new Array();      start = start || 0;      end = end || this.length;      for(var i = start; i < end; i++){           result.push(this[i]);      }      return result;   }
 
  | 
 
splice()
splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。
此方法会改变原数组
删除
第二个参数为删除的个数
var ary =[1,2,3,4,5,6]
  ary.splice(1,1);    ary  
   | 
 
插入
var ary =[1,2,3,4,5,6] ary.splice(2, 0, "7");    ary  
  ary.splice(2, 0, "9",'10',11,12) ary  
   | 
 
删除 & 插入
var myFish = ['angel', 'clown', 'trumpet', 'sturgeon']; myFish.splice(0, 2, 'parrot', 'anemone', 'blue');  myFish  
   | 
 
filter() 实现
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
注意: filter() 不会改变原始数组。
注意: filter() 不会对空数组进行检测。
语法
array.filter(function(currentValue,index,arr), thisValue)
Array.prototype.selfFilter = function(callback, context) {      if (this === null) {     throw new TypeError(       "Array.prototype.reduce" + "called on null or undefined"     );   }      if (typeof callback !== "function") {     throw new TypeError(callback + " is not a function");   }      let aArr = Array.prototype.slice.call(this);   let _len = aArr.length;   let aFArr = [];      for (let i = 0; i < _len; i++) {     if (!aArr.hasOwnProperty(i)) {       continue;     }     callback.call(context, aArr[i], i, this) && aFArr.push(aArr[i]);   }   return aFArr; };
  | 
 
所有的数组方法集合
改变原数组的方法:
 pop():移除数组末尾的最后一个元素,并返回该元素的值。 push():向数组末尾添加一个或多个元素,并返回新数组的长度。 shift():移除数组的第一个元素,并返回该元素的值。 unshift():在数组的开头添加一个或多个元素,并返回新数组的长度。 splice():向/从数组中添加/删除项目,然后返回被删除的项目。 reverse():颠倒数组中元素的顺序。 sort():对数组的元素进行排序,并返回排序后的数组。 fill():使用一个固定值填充数组的所有元素。 copyWithin():从数组的指定位置拷贝元素到数组的另一个指定位置。 set() (TypedArray):用于通过拷贝数组或者数值来填充 TypedArray。
 
  | 
 
不改变原数组的方法:
concat():连接两个或多个数组,并返回一个新数组。 slice():从已有的数组中返回选定的元素。 join():把数组中的所有元素放入一个字符串。 indexOf():搜索数组中的元素,并返回它所在的位置索引,如果没有找到则返回 -1。 lastIndexOf():从数组的末尾开始搜索元素,并返回它所在的位置索引,如果没有找到则返回 -1。 includes():判断数组是否包含一个指定的值,如果是返回 true,否则返回 false。 every():检查数组中的所有元素是否都符合指定条件。 some():检查数组中是否至少有一个元素符合指定条件。 filter():创建一个新数组,其中包含所有通过所提供函数实现的测试的元素。 map():创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。 forEach():对数组中的每个元素执行提供的函数。 reduce():对数组中的每个元素执行一个累积器函数(从左到右),将其结果汇总为单个返回值。 reduceRight():对数组中的每个元素执行一个累积器函数(从右到左),将其结果汇总为单个返回值。 find():返回数组中满足提供的测试函数的第一个元素的值,否则返回 undefined。 findIndex():返回数组中满足提供的测试函数的第一个元素的索引,否则返回 -1。
   | 
 
Map + Set + WeakMap + WeakSet
 const set = new Set();
  // 添加值 set.add(1); set.add(2); set.add(3); set.add(3); // 重复值不会被添加
  // 检查是否存在某个值 console.log(set.has(1)); // true console.log(set.has(4)); // false
  // 获取 Set 的大小 console.log(set.size); // 3
  // 删除值 set.delete(2); console.log(set.has(2)); // false
  // 遍历 Set 的值 for (const value of set.values()) {   console.log(`Value: ${value}`); }
 
  for (const key of set.keys()) {   console.log(`Key: ${key}`); }
 
  for (const [key, value] of set.entries()) {   console.log(`Entry: ${key} = ${value}`); }
 
  set.forEach((value) => {   console.log(`ForEach Value: ${value}`); });
 
  set.clear(); console.log(set.size); // 0
 
  // WeakSet // WeakSet 是 JavaScript 中的一种集合类型,它与 Set 类似,但有一些关键区别和限制。WeakSet 只能存储对象类型的值,并且对这些对象持有弱引用,这意味着如果没有其他引用指向这些对象,它们可以被垃圾回收机制回收。 const weakSet = new WeakSet(); const obj1 = {}; const obj2 = {}; const obj3 = {};
 
  weakSet.add(obj1); weakSet.add(obj2);
 
  console.log(weakSet.has(obj1));  console.log(weakSet.has(obj3)); 
 
  weakSet.delete(obj2); console.log(weakSet.has(obj2)); 
 
  obj1 = null; obj3 = null;
 
 
 
 
  const map = new Map();
 
  map.set('key1', 'value1'); map.set('key2', 'value2'); map.set('key3', 'value3');
 
  console.log(map.get('key1')); 
 
  console.log(map.has('key2')); 
 
  map.delete('key2'); console.log(map.has('key2')); 
 
  console.log(map.size); 
 
  for (const key of map.keys()) {   console.log(`Key: ${key}`); }
 
  for (const value of map.values()) {   console.log(`Value: ${value}`); }
 
  for (const [key, value] of map.entries()) {   console.log(`Entry: ${key} = ${value}`); }
 
  map.forEach((value, key) => {   console.log(`${key}: ${value}`); });
 
  map.clear(); console.log(map.size); 
 
 
 
  const weakMap = new WeakMap(); const obj1 = {}; const obj2 = {}; const obj3 = {};
 
  weakMap.set(obj1, 'value1'); weakMap.set(obj2, 'value2'); weakMap.set(obj3, 'value3');
 
  console.log(weakMap.get(obj1)); 
 
  console.log(weakMap.has(obj2)); 
 
  weakMap.delete(obj2); console.log(weakMap.has(obj2)); 
 
  console.log(weakMap.get(obj2)); 
 
  obj1 = null; obj3 = null;
 
 
 
  | 
 
Set 和 Map 区别
Set 和 Map 在 JavaScript 中确实有许多相似之处,但它们在用途和行为上有显著的区别。下面是对两者的详细比较:
相似之处
- 集合类型:
Set 和 Map 都是集合类型,用于存储唯一的元素。 
- 内置方法:两者都有类似的方法来操作其元素,例如添加、删除、查找、清空等。
 
- 迭代器:都提供了迭代器方法(如 
keys、values、entries)用于遍历集合中的元素。 
- 迭代顺序:两者都保持插入元素的顺序,因此迭代时按照插入顺序进行。
 
不同之处
- 存储的元素:
- Set:存储的是一组唯一的值。值可以是任何类型,包括原始值和对象。
 
- Map:存储的是一组键值对。键和值都可以是任何类型。
 
 
- 键和值:
- Set:每个元素即是值,没有键的概念。
 
- Map:每个元素是一个 
[key, value] 对,键和值都可以是任意类型。 
 
- 方法:
- Set:
add(value):添加一个值到集合中。 
has(value):检查集合中是否存在某个值。 
delete(value):从集合中删除一个值。 
clear():清空集合。 
values()、keys()、entries()、forEach():用于迭代集合中的值。 
 
- Map:
set(key, value):添加或更新一个键值对。 
get(key):获取与键关联的值。 
has(key):检查集合中是否存在某个键。 
delete(key):从集合中删除一个键值对。 
clear():清空集合。 
values()、keys()、entries()、forEach():用于迭代集合中的键值对。 
 
 
用途和使用场景
Set:
- 用于存储唯一值的集合,可以用于数组去重。
 
- 适用于需要快速查找唯一值的场景。
 
示例:
const set = new Set(); set.add(1); set.add(2); set.add(2); // 不会添加重复值 console.log(set.has(1)); // true console.log(set.size); // 2
   | 
 
 
Map:
- 用于存储键值对,特别适合需要基于键进行快速查找、添加和删除操作的场景。
 
- 适用于需要关联数据对的场景,比如字典、缓存等。
 
示例:
const map = new Map(); map.set('key1', 'value1'); map.set('key2', 'value2'); console.log(map.get('key1'));  console.log(map.has('key2'));  console.log(map.size); 
   | 
 
 
Object 和 Map 区别
Map 和普通的对象(Object)在存储键值对的基本功能上有些类似,但它们在设计目的和使用场景上有一些重要的区别和优势:
区别和优势
键的类型:
Object:键必须是字符串或者 Symbol 类型。如果键不是字符串或者 Symbol,则会被转换为字符串。
Map:键可以是任意类型,包括基本类型(如字符串、数字、布尔值)、对象和函数等。这使得 Map 在处理复杂的键值关系时更加灵活。
插入顺序:
Object:对象的属性在添加时不保证任何顺序,遍历时的顺序可能不同于添加时的顺序。
Map:保持键值对的插入顺序,迭代时按照插入顺序进行,这点与 Array 类似。
性能:
Object:对象适合于存储简单的键值对,并且在属性较少、直接量赋值的情况下性能很好。
Map:Map 在处理大量数据、频繁增删键值对、需要快速查找特定键等方面通常比对象更高效。
可迭代性:
Object:需要额外处理才能进行迭代,比如使用 Object.keys(obj)、Object.values(obj) 或者 Object.entries(obj)。
Map:直接支持迭代器接口,可以通过 for…of、forEach 等方式遍历键值对。
内存管理:
Object:作为引用类型,对象属性被引用时会增加对象的引用计数,可能导致对象不被及时回收。
Map:对键的引用是弱引用,这意味着即使 Map 持有对象的引用,该对象也可以被垃圾回收。
数组去重
 function unique(arr, fn) {   return arr.reduce(fn, []); } unique([1,2,3,3,2,1,15,6], function(arr, item) {   !arr.includes(item) && arr.push(item);   return arr; });
 
  | 
 
forEach中return有效果吗?如何中断forEach循环?
在forEach中用return不会返回,函数会继续执行。
let nums = [1, 2, 3]; nums.forEach((item, index) => {   return; })
   | 
 
中断方法:
(1). 使用try监视代码块,在需要中断的地方抛出异常。
(2). 官方推荐方法(替换方法):用every和some替代forEach函数。every在碰到return false的时候,中止循环。some在碰到return true的时候,中止循环
js将多维数组转换为一维数组
 let arr = [1, 2, 3, 4, 5, [6, 7, 8, [9, 10, 11, 12, [13, 14, 15, 16]]]] console.log(arr.join())   
  let newArr = arr.join().split(',') let newArr = arr.toString().split(',') let newArr = (arr + '').split(',')
 
  console.log(newArr) 
 
  | 
 
递归
let arr = [1, 2, 3, 4, 5, [6, 7, 8, [9, 10, 11, 12, [13, 14, 15, 16]]]] let newArr = []  function arrConversion (arr) {   for (let i = 0; i < arr.length; i++) {     if (Array.isArray(arr[i])) {       arrConversion(arr[i])     } else {       newArr.push(arr[i])     }   } } arrConversion(arr) console.log(newArr)
   | 
 
循环
function flatArray(ary) {   let result = [];   while (ary.length) {     let item = ary.shift();     if (Array.isArray(item)) {       ary.unshift(...item);     } else {       result.push(item);     }   }   return result; }
  | 
 
flat
console.log([1 ,[2, 3]].flat());   
  console.log([1, [2, [3, [4, 5]]]].flat(2));   
  console.log([1, [2, [3, [4, 5]]]].flat(Infinity)); 
   | 
 
正则
let ary = [1, [2, [3, [4, 5]]], 6]; let str = JSON.stringify(ary); let result = str.replace(/(\[|\])/g, '').split(','); console.log( result )
   | 
 
数组快速随机排序
let arr =[1,2,3,4];
  let t; for(let i = 0;i < arr.length; i++){   let rand = parseInt(Math.random()*arr.length);      t = arr[rand];      arr[rand] =arr[i];      arr[i] = t; }
  arr.sort(()=>{   return Math.random() - 0.5; })
   | 
 
数组排序
function selectSort(arr) {     var len = arr.length;     for(let i = 0 ;i < len - 1; i++) {         for(let j = i ; j<len; j++) {             if(arr[j] < arr[i]) {                 [arr[i],arr[j]] = [arr[j],arr[i]];             }         }     }     return arr }
  function quickSort(arr) {     if(arr.length <= 1) {         return arr;       }     var left = [],         right = [],         current = arr.splice(0,1);      for(let i = 0; i < arr.length; i++) {         if(arr[i] < current) {             left.push(arr[i])           } else {             right.push(arr[i])          }     }     return quickSort(left).concat(current,quickSort(right)); }
  | 
 
判断数组中是否有重复元素
let arr = [1,2,3,4,4]
  function isRepeat(arr) {   let flag = false;   for(var i = 0; i < arr.length; i++) {     for(var j = i + 1; j < arr.length; j++) {       if (arr[i] === arr[j]) {         flag = true;         break;       }     }   }   return flag }
  function isRepeat(arr) {   let obj = {}   for(var i = 0; i < arr.length; i++) {    obj[arr[i]] = arr[i]   }   return Object.keys(obj).length !== arr.length }
   | 
 
求第一个数组中没有第二个数组中部分的值
差集
 function differenceSecond(ary1,ary2){     let arr = []     ary1.filter((item)=>{       !ary2.includes(item)&&arr.push(item)     })     return arr }
  function differenceSecond(m, n) {   let a = [...m, ...n];   let b = n;   let aHasNaN = m.some(function(v) {     return isNaN(v);   });   let bHasNaN = n.some(function(v) {     return isNaN(v);   });   let difference = a     .filter(function(v) {       return b.indexOf(v) == -1 && !isNaN(v);     })     .concat(       b.filter(function(v) {         return a.indexOf(v) == -1 && !isNaN(v);       })     )     .concat(aHasNaN ^ bHasNaN ? [NaN] : []);   return difference; }
 
  | 
 
简单实现判断两个数组是不是相同
在 JavaScript 中,可以通过以下步骤来实现这一点:
检查数组的长度是否相同。
如果长度相同,逐个比较对应位置上的元素。
下面是一个示例函数,用于判断两个数组是否相同:
function arraysAreEqual(arr1, arr2) {      if (arr1.length !== arr2.length) {     return false;   }
       for (let i = 0; i < arr1.length; i++) {     if (arr1[i] !== arr2[i]) {       return false;     }   }
       return true; }
 
  const array1 = [1, 2, 3, 4]; const array2 = [1, 2, 3, 4]; const array3 = [1, 2, 3, 5];
  console.log(arraysAreEqual(array1, array2));  console.log(arraysAreEqual(array1, array3)); 
  | 
 
判断两个对象是否相同
要判断两个对象是否相同,需要进行深度比较,因为直接比较对象的引用(使用 === 或 ==)只会检查它们是否引用同一个内存地址,而不是检查它们的内容是否相同。
function deepEqual(obj1, obj2) {      if (obj1 === obj2) {     return true;   }
       if (typeof obj1 !== 'object' || typeof obj2 !== 'object' || obj1 === null || obj2 === null) {     return false;   }
       const keys1 = Object.keys(obj1);   const keys2 = Object.keys(obj2);
       if (keys1.length !== keys2.length) {     return false;   }
       for (let key of keys1) {     if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) {       return false;     }   }
    return true; }
 
  const obj1 = { a: 1, b: { c: 2 } }; const obj2 = { a: 1, b: { c: 2 } }; const obj3 = { a: 1, b: { c: 3 } };
  console.log(deepEqual(obj1, obj2));  console.log(deepEqual(obj1, obj3)); 
  | 
 
参考文档
MDN ARRAY