javascript 对象类型之 - Array

概述

var arr = [] ;
typeof arr; // 'object'

创建方式

// 1.字面量式
var arr1 = []; 
var arr2 = [1,2,3]; 

// 2.构造式
var arr3 = new Array(); // []
var arr4 = new Array(1,2,3); // [1,2,3]

var arr5 = new Array(3); // 
// 打印 3 次 undefined
for(var i=0;i<arr5.length;i++){
    consoel.log(arr5[i])
}
// 一次都不打印, 类似的还有 map ,every 等
arr5.forEach(item=>{
    console.log(1);
    console.log(item);
})

// 3. 具备 length 属性的伪数组通过 Array.from 转换
// 3-1
var str = '1234'
var arr6 = Array.from(str); // ['1','2','3','4']

// 3-2
var aLis = document.getElementsByTagName('li');
var aLis2 = Array.from(aLis);

// 3-3
function test(a,b,c){
    var args = Array.from(arguments);
}

// 3-4
var obj = {1:1,2:2,a:1,length:5}
Array.from(obj); // [undefined,1,2,undefined,undefined]

判断是否是数组

// 1. Array.isArray
var arr = []
Array.isArray(arr); // true

// 2. 
var isArray = (obj) => Object.prototype.toString.call(obj) === '[object Array]';
isArray(arr);

数组的基本方法

基本方法之 - 查找
  • indexOf => 元素所在的索引 || -1
var arr =[1,2,3,4,5]
var index = arr.indexOf(3); // 2
var index2 = arr.indexOf(10); // -1

// 判断是否在函数中 => Boolean
var isInArr = (val,arr)=>arr.indexOf(val) !== -1 ;
  • includes ,数组中是否包含元素 ; => Boolean
var arr = [1,2,3,4,5]
var hasFive = arr.includes(5); // true
var hasSix = arr.includes(6); // false
  • find ,找到第一个直接返回该元素; 遍历完整个数组未找到, 返回 undefined => ArrayItem || undefined
var arr = ['x','xx','xxx','xxxx']
var result = arr.find(item=>{
    console.log('loop'); 
    return item.length>2;
})
// 以上, 仅打印 3 次 'loop', 则说明提前中断了遍历返回, 最后返回 'xxx'

var result2 = arr.find(item=>{
    console.log('loop');
    return item.length>4;
})
result2; // undefined
  • findIndex 找到满足条件的位置索引, 提前找到符合条件的, 提前返回 , 结束整个迭代 ; 迭代完整个数组未找到则返回 -1 => arrayItemIndex || -1
var arr = ['x','xx','xxx','xxxx']
var result = arr.findIndex(item=>{
    console.log('loop'); 
    return item.length>2;
})
// 以上, 仅打印 3 次 'loop', 则说明提前中断了遍历返回, 最后返回 2

var result2 = arr.findIndex(item=>{
    console.log('loop');
    return item.length>4;
})
result2; // -1
基本方法之 - 操作
对原数组无影响
  • join , 将数组元素用特定的字符( 默认为逗号)拼接成字符串 => String
var arr = [1,2,3,4]

var str1 = arr.join(); 
console.log(str1); // '1,2,3,4'

var str2 = arr.join('&');
console.log(str2); // '1&2&3&4'
  • concat; 合并多个数组或元素 => Array

参数可为数组 , 多个数组, 单个元素, 多个单个元素. 单个元素和数组混杂

var arr = [1,2,3,4]
var arr2 = [5,6,7,8]

var mergeArr = arr.concat(arr2); 
console.log(mergeArr); // [1,2,3,4,5,6,7,8]

var newArr1 = arr.concat(5); // [1,2,3,4,5]
var newArr2 = arr.concat([5]);  // [1,2,3,4,5]
var newArr3 = arr.concat(5,6,7); // [1,2,3,4,5,6,7]
var newArr4 = arr.concat([5],[6,7]); // [1,2,3,4,5,6,7]
var newArr5 = arr.concat(5,[6,7]); // [1,2,3,4,5,6,7]

// 扩展符类似 concat 
var newArr6 = [...arr,5,6,7]; // [1,2,3,4,5,6,7]
  • slice(startIndex,endIndex), 从原数组拷贝一份下来, 从startIndex 开始(包括) 到 endIndex 结束( 不包括) => Array
var arr = ['x','xx','xxx','xxxx','xxxxx']
arr.slice(3); // ['xxxx','xxxxx']
arr.slice(3,3); // []
arr.slice(3,4); // ['xxxx']
对原数组有影响

直接在原数组上操作的方法, 会改变原数组的元素.

  • sort , 排序, 返回排序后的数组 => Array
// 1.正序
var arr = [1,9,3,2,5,8]
arr.sort(); // [1, 2, 3, 5, 8, 9]

// 或
var arr2 = [1,9,3,2,5,8]
arr2.sort((a,b)=>a-b); // [1, 2, 3, 5, 8, 9]

// 2.倒序
var arr3 = [1,9,3,2,5,8]
arr3.sort((a,b)=>b-a); // [9, 8, 5, 3, 2, 1]
  • push , 往数组元素的末尾添加元素, 返回新数组长度 => Array.length
var arr = [1,2,3]
arr.push(4); // 4
arr.push(5,6); // 6
arr.push(...[7,8]); // 8
console.log(arr); // [1,2,3,4,5,6,7,8]
  • unshift, 往数组元素的首端添加元素, 返回新数组长度 => Array.length
var arr = [1,2,3];
arr.unshift(0); // 4
arr.unshift(-2,-1); // 6
arr.unshift(...[-4,-3]); // 8
console.log(arr); // [-4, -3, -2, -1, 0, 1, 2, 3]
  • pop, 从数组末端删除一个元素, 返回被删除的元素 => ArrayItem
var arr = ['a','b','c','d']
arr.pop(); // 'd'
arr.pop(); // 'c'
console.log(arr); // ['a','b']
  • shift , 从数组首端删除一个元素, 返回刚删除的元素 => ArrayItem
var arr = ['a','b','c','d']
arr.shift(); // 'a'
arr.shift(); // 'b'
console.log(arr); // ['c','d']
  • reverse, 数组反向, 返回反向后的数组 => Array
var arr = [1,2,3,4]
arr.reverse();
console.log(arr); // [4,3,2,1]
  • splice(startIndex,num); 从原数组上切割下来一块, 返回切割下来的一块 => Array
var arr = ['x','xx','xxx','xxxx','xxxxx']
arr.splice(); // []

// 只一个参数时, 表示从开始位置切割到最后位置
var arr2 = ['x','xx','xxx','xxxx','xxxxx']
arr2.splice(0); // ['x','xx','xxx','xxxx','xxxxx']

// 两个参数, 表示从 startIndex 切割 num 个元素.
var arr3 = ['x','xx','xxx','xxxx','xxxxx']
arr3.splice(1,0); // []
arr3.splice(1,1); // ['xx']

// 三个或三个以上参数, 表示从切开位置, 填入新元素
var arr4 = ['x','xx','xxx','xxxx','xxxxx']
arr4.splice(1,1,'hello','hi'); //  ["x", "hello", "hi", "xxx", "xxxx", "xxxxx"]
基本方法之 - 迭代

类型转换

  • 其他转数组
// 1. 字符串转数组
var str1 = '1,2,3,4'
var arr1 = str1.split(',');

// 2. json 对象转数组, 对象必须有 length 属性, 会忽略键名非数字项
var obj = {1:1,0:2,a:1,length:5};
var arr2 = Array.from(obj);
  • 数组转其他
// 1. 数组转字符串 join
var arr1 = ['a','b','c','d']

// 1-1 默认合并字符为 , 
var str1 = arr1.join(); // 'a,b,c,d'

// 1-2 自定义合并字符
var str2 = arr1.join('-');
console.log(str2) ;// 'a-b-c-d'

数组应用

  • 遍历多维数组
var arr = [1,[2,[3,[4,[5]]]]];
function deepForEach(arr, fn) {
  arr.forEach(item => Array.isArray(item) 
                              ? deepForEach(item, fn) 
                              : fn(item))
}

deepForEach(arr, item => {
  console.log(item)
})
  • 展平多维数组
// 常规解法
var arr = [1,[2,[3,[4,[5]]]]];
function flatten(arr, result = []) {
  for (var i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      flatten(arr[i], result);
    }
    else {
      result.push(arr[i])
    }
  }
  return result;
}

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

// 换种写法
function flatten(arr) {
  var result = [];
  for (var i = 0; i < arr.length; i++) {
    result = result.concat(Array.isArray(arr[i]) ? flatten(arr[i]) : arr[i])
  }
  return result;
}

// reduce 解法
var flatten = (arr) => arr.reduce((prev, now) => {
  return prev.concat(Array.isArray(now) ? flatten(now) : now)
}, []);

flatten(arr); 
  • 树形结构
var originData = [
  { title: '标题1', id: '1', pid: '0' },
  { title: '标题1-1', id: '1-1', pid: '1' },
  { title: '标题1-2', id: '1-2', pid: '1' },
  { title: '标题2', id: '2', pid: '0' },
  { title: '标题2-1', id: '2-1', pid: '2' },
  { title: '标题2-2', id: '2-2', pid: '2' },
  { title: '标题2-1-1', id: '2-1-1', pid: '2-1' },
  { title: '标题2-2-1', id: '2-2-1', pid: '2-2' },
  { title: '标题2-2-2', id: '2-2-2', pid: '2-2' },
  { title: '标题2-2-2-1', id: '2-2-2-1', pid: '2-2-2' },
  { title: '标题2-2-2-2', id: '2-2-2-2', pid: '2-2-2' },
];

// 常规
function toTree(arr, pid) {
  var treeArr = [];
  var allTreeLeaf = arr.filter(item => item.pid === pid);
  allTreeLeaf.forEach(tree => {
    let _children = toTree(arr, tree.id)
    if (_children.length) {
      tree.children = _children;
    }
    treeArr.push(tree);
  })
  return treeArr;
}

var formatTree = toTree(originData,'0');

// 将树形展平还原回去
function flattenTree(treeData, linkKey) {
  var result = [];
  treeData.forEach(thrunk => {
    if (thrunk[linkKey] && thrunk[linkKey].length) {
      result = result.concat(flattenTree(thrunk.children, linkKey))
    }
    delete thrunk[linkKey]
    result = result.concat(thrunk);
  })
  return result;
}

console.log(flattenTree(formatTree, 'children'))
  • 求数组中最大值
// 1. 常规
function getMax(arr){
    var max = arr[0]
    arr.forEach(item=>{
        max = item>max? item:max;
    })
    return max;
}

// 2.常规用 reduce 变式
function getMax(arr) {
  return arr.reduce((prev, now) => Math.max(prev,now))
}

// 3. max 直接求最大, 好吧, max 是可以传多个参数的
var getMax = (arr)=>Math.max(...arr);

// 4. 先排序,再末尾元素值 => 副作用, 在原数组的操作, 会影响原数组,鸡肋
var getMax = (arr)=>arr.sort((a,b)=>b-a)[0];
var getMax = (arr)=>arr.sort().reverse()[0];

// 5. 利用对象的键名自动排序原理
function getMax(arr){
    var obj = {}
    arr.forEach((item)=>{
        obj[item] = item;
    });
    var keys = Object.keys(obj);
    return Number(keys[keys.length-1]);
}

最简直的还是直接用 Math.max(...arr)

  • 数组去重
var arr = [1,3,4,2,3,5,12,5]
// 1. 常规, => for 式
function unique1(arr){
    var uniqueArr = []
    arr.forEach(item=>{
        if(!uniqueArr.includes(item)){
            uniqueArr.push(item);
        }
    })
    return uniqueArr
}

// 2. 对象键名不可重复性, => obj 式
function unique2(arr){
    var obj = {}
    arr.forEach(item=>{
        obj[item] = item
    })
    return Object.values(obj);
}

console.log(unique(arr))

// 3. Set
var unique3 = (arr)=>[...new Set(arr)]

// 4. Map , 和方法 2 的用对象转换类似
// 原理解释 : 如果 map 里面已经有该键, 则返回false ; 如果没有 则设置该键, 并且返回true; filter 接收到这个true , 把它添加到结果数组中.
function unique4(arr){
   var tmp = new Map();
   return arr.filter(item => {
       return !tmp.has(item) && tmp.set(item, 1);
   })
}

// 5. json 对象的类似 Map 解法 , => obj-map 式
function unique5(arr){
    var obj = {}
    return arr.filter(item=>{
        return !obj[item] && Object.assign(obj,{[item]:''})
    })
}

时间效率上: Set > Map > obj 式 > obj-map 式 > for 式

猜你喜欢

转载自blog.csdn.net/haokur/article/details/80524856