javascript 数组

379 阅读6分钟

javascript 数组

var arr = ['a','b','c']
console.log(arr.toString()) // a,b,c
console.log(arr.valueOf()) // ["a", "b", "c"]
console.log(arr) // ["a", "b", "c"]
console.log(arr.join('--')) // a--b--c

var arr2 = [undefined,'b',null] 
console.log(arr2.toString()) //  ,b,

1、数组创建

创建数组的基本方式有两种

  1. 使用 Array构造函数 var arr = new Array() 或者 var arr = Array("a","b")
  2. 使用 数组字面量 [] var arr = [2,3]

数组最后一项的索引始终是length-1,因此下一个新项的位置就是length

2、数组的检测

两种方式

  • instanceof 操作符,语法 arr instanceof Array
  • Array.isArray(arr) ECMAScript5 新增方法

两者区别,前者在存在2个以上的全局环境时,会存在两个以上的Array构造函数

当检测Array实例时, Array.isArray 优于 instanceof,因为Array.isArray能检测iframes.

3、栈和队列

**后进先出** LIFO

  1. 栈中的插入和移除的位置只会发生在栈的顶部。
  2. arr.push(value) 往数组末尾追加,并返回修改后数组的长度
  3. arr.pop() 减少数组的长度,并返回数组的最后一项
2020_07_23_cQQA3r
2020_07_23_cQQA3r

队列**先进先出** FIFO

  1. arr.push() 向数组末端添加
  2. arr.shift(value) 移除数组的第一个项,并返回该项目

shift 和 push 配合,队列是在列表的末端添加,从列表的前端移除.

  1. arr.unshift(value) 在数组前端添加任意个项,并返回新数组的长度
  2. arr.pop() 减少数组的长度,并返回数组的最后一项

unshift 和 pop 配合。可以相反方向来模拟队列,即在数组的前面添加,从数组末端移除.

2020_07_23_N5v5SR
2020_07_23_N5v5SR

4、重新排序方法,改变原数组

数组直接用来排序的有 reverse()sort()

  • reverse() 直接反转数组
  • sort() 可以接受一个比较函数,默认不传,则会根据数组项的字符串比较
  • arr.sort(function (a,b) { return a-b}) 数值会保证正确的升序,字符串还是保持不变
var arr = [1,2,4,22,23,14,'a','c','b']

# localeCompare() 方法返回一个数字来指示一个参考字符串是否在排序顺序前面或之后或与给定字符串相同。 
arr.sort((a, b) => {
  if( typeof a == 'string' && typeof b == 'string'){
    return b.localeCompare(a)
  }else {
    return b - a
  }
})
console.log(arr) // [ 23, 22, 14, 4, 2, 1, 'c', 'b', 'a' ]
console.log(arr.reverse()); // [ 'a', 'b', 'c', 1, 2, 4, 14, 22, 23 ]

localeCompare() 方法


5、查找位置的方法

  • indexOf(value,location) 从数组开头往后查找。
  • lastIndexOf(value,location) 从数组的结尾往前查找
  • 参数value 要查找的项,location 从那个位置开始找,indexOf里默认不写的话为0,lastIndexOf里默认为arr.lenght-1
  • 两者都返回要查找的项在数组中的位置,没找到的情况返回-1,匹配时是使用全等 ===

6.操作方法concat(),slice() 创建新数组,不改变原数组

  • concat() 基于当前数组创建一个新数组,原数组不改变。
  • slice() 基于当前数组中的一个或多个项,创建一个新数组,原数组不改变。
    • 当只有一个参数时,返回从该参数指定的位置到当前数组结尾的所有项
    • 如果有两个参数,返回起始和结束位置之间的项,但不包括结束位置的项,即含头不含尾
    • 如果参数有负数,则用数组长度+该数来确定相应的位置
  • splice() 可以删除、插入、替换 改变原数组
    • 删除,两个参数:要删除的第一项的位置要删除的项数
    • 插入,三个参数:起始位置要删除的项数要插入的项
    • 替换:三个参数:起始位置要删除的项数要插入的项
# concat()
var arr = [1,2,3]
var x = arr.concat('2') 
console.log(arr,x); // [ 1, 2, 3 ] [ 1, 2, 3, '2' ]

# slice()
var arr2 = ['a','b','c',1,3,4]
var item = arr2.slice(1)
console.log(item,arr2); // [ 'b', 'c', 1, 3, 4 ] [ 'a', 'b', 'c', 1, 3, 4 ]
var item2 = arr2.slice(0,3)
console.log(item2,arr2); // [ 'a', 'b', 'c' ] [ 'a', 'b', 'c', 1, 3, 4 ]

# splice() **删除**
var arr3 = ['a','b','c']
var item3 = arr3.splice(0,2)
console.log(item3,arr3); // [ 'a', 'b' ] [ 'c' ]

# splice() **插入**
var arr4 = ['a','b','c']
var item4 = arr4.splice(0,2,'zan','asd')
console.log(item4,arr4); // [ 'a', 'b' ] [ 'zan', 'asd', 'c' ]

# splice() **替换**
var arr5 = ['a','b','c']
var item5 = arr5.splice(0,1,'zan','666')
console.log(item5,arr5); [ 'a' ] [ 'zan', '666', 'b', 'c' ]

7、迭代方法

JavaScript标准内置对象 Array

  • every() // 每一项为true,则返回true
  • filter() // 返回true 的项组成的数组
  • forEach() // 对数组中的每一项运行给定的函数,没有返回值
  • map() // 返回函数调用的结果组成的数组
  • some() // 某一项为true,则返回true

8、归并方法

  • reduce() 从数组第一项开始遍历

  • reduceRight() 从数组最后一项开始,向前遍历

    都会迭代数组的所有项,然后构建一个最终的返回值。

    reduce()

var total = [ 0, 1, 2, 3 ].reduce(
  ( acc, cur ) => acc + cur, 0   // acc 累计器累计回调的返回值  cur 数组中正在处理的元素。
);

# 将二维数组转化为一维
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
 ( acc, cur ) => acc.concat(cur),
 []
);  // flattened is [0, 1, 2, 3, 4, 5]

# 计算数组中每个元素出现的次数
let names = ["Lily", "Barry", "Dendi", "Boogie", "Lily"];
let nameNum = names.reduce((pre, cur) => {
  if (cur in pre) { 
    //pre 中是否有 cur 属性
    pre[cur]++;
  } else {
    pre[cur] = 1; //为 pre 这个对象添加 cur 属性,并且赋值为 1
  }
  return pre;
}, {}); //reduce(), ES6数组归并方法,这里初始值设置为一个空对象

console.log(nameNum); //{Barry: 1,Boogie: 1,Dendi: 1,Lily: 2  }

# 按属性对object分类
var people = [
  { name: 'Alice', age: 21 },
  { name: 'Max', age: 20 },
  { name: 'Jane', age: 20 }
];

function groupBy(objectArray, property) {
  return objectArray.reduce(function (acc, obj) {
    var key = obj[property];
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(obj);
    return acc;
  }, {});
}

var groupedPeople = groupBy(people, 'age');
// { '20': [ { name: 'Max', age: 20 }, { name: 'Jane', age: 20 } ],
//  '21': [ { name: 'Alice', age: 21 } ] }

# 数组去重
var myArray = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd', 'd', 'd'];
var myOrderedArray = myArray.reduce(function (accumulator, currentValue) {
  if (accumulator.indexOf(currentValue) === -1) {
    accumulator.push(currentValue);
  }
  return accumulator
}, [])

console.log(myOrderedArray);

9、其他常用

  • flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。var newArray = arr.flat([depth]) 使用Infinity ,可展开任意深度的嵌套数组,会移除数组中的空项. undefinednull 不会去除。
  • includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。比较字符串和字符时是区分大小写。
  • Array.from() 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
  • Array.isArray() 用于确定传递的值是否是一个 Array
    • 当检测Array实例时, Array.isArray 优于 instanceof,因为Array.isArray能检测iframes.
# flat()
var arr = [1, 2, , undefined, null, 4, 5];
arr.flat();  // [1, 2,undefined, null, 4, 5];


// for of 循环不能去除数组空位,需要手动去除
const forFlat = (arr = [], depth = 1) => {
  const result = [];
  (function flat(arr, depth) {
    for (let item of arr) {
      if (Array.isArray(item) && depth > 0) {
        flat(item, depth - 1)
      } else {
        // 去除空元素,添加非undefined元素
        item !== void 0 && item !==null && result.push(item);
      }
    }
  })(arr, depth)
  return result;
}
console.log(forFlat(arr)); // [ 1, 2, 4, 5 ]

# includes()
(function() {
  console.log([].includes.call(arguments, 'a')); // true
  console.log([].includes.call(arguments, 'd')); // false
})('a','b','c');

# Array.from()
console.log(Array.from('foo'));
// expected output: Array ["f", "o", "o"]

console.log(Array.from([1, 2, 3], x => x + x));
// expected output: Array [2, 4, 6]
# 数组去重合并
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));   

# Array.isArray 优于 instanceof,因为Array.isArray能检测iframes.
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]

// Correctly checking for Array
Array.isArray(arr);  // true
// Considered harmful, because doesn't work though iframes
arr instanceof Array; // false

本文使用 mdnice 排版

文章列表

JavaScript 基本概念

JavaScript 数据类型

JavaScript 基本类型和引用类型

javascript 执行环境和作用域

javascript 垃圾收集机制

javascript 数组