Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript Secrets of the Array Ninja #9

Open
bouquetrender opened this issue May 9, 2018 · 0 comments
Open

JavaScript Secrets of the Array Ninja #9

bouquetrender opened this issue May 9, 2018 · 0 comments

Comments

@bouquetrender
Copy link
Owner

好吧我承认标题是从《Secrets of the JavaScript Ninja》这本书抄过来的,在网上偶尔会看到一些JS数组操作整理但都不全,所以想着为何我不自己写一篇来总结一下而且也可当做查阅文档使用。最后一部分还包含了一些 jQuery 的操作。

JavaScript 数组操作

截取

对数组进行部分截取,并返回一个数组副本。

[1,2,3].slice(x)  // 从数组索引x开始截取,大于数组长度则返回空数组
[1,2,3].slice(x,y+1)  // 从数组索引x开始截取到y
[1,2,3].slice(-x)  // 从数组结尾开始截取x,如果负数大于数组长度则截取整个数组 
[1,2,3].slice(x, -y)  // length也会先于负数相加后,再截取

关于栈和队列

栈LIFO(Last-In-First-Out)后进先出的数据结构,最新添加的项最早被移除。而栈中项的插入和移除,只发生在栈的顶部。push()和pop()方法实现了类似栈的行为。

队列FIFO(First-In-First-Out)先进先出的数据结构,一开始添加的项最早被移除。队列在列表的末端添加项,从列表的前端移除项。

检测

if (value instanceof Array){ //do something }
if (Array.isArray(value)){ //do something }
if (Object.prototype.toString.call(value).slice(8, -1)){ //do something }

字符串化

如果数组中的某一项的值是null 或者undefined,那么该值在join()、toLocaleString()、toString()和valueOf()方法返回的结果中以空字符串表示。返回结果为string字符串。

join() 返回由数组元素组成并由 seperator 分隔的字符串。若 seperator 为空,则默认以 “,” 连接;
["red", "green", "blue"].join(seperator);

Array.toString()和Array.toLocaleString()
两种方法的区别在于 toLocaleString() 会转变为本地环境字符串(如Date.toLocalString()会转化为当地时间格式的字符串),toString() 则转为传统字符串; Array的这两种方法用法无区别

在数组末尾添加或删除元素

将一个或多个元素附加在数组末尾,并返回新数组长度 Array.push(value1, value2, vlaue3, …);

移除数组最后一个值,并返回该元素值 Array.pop();

在数组开始添加或删除元素

将一个或多个元素附加在数组开头,原数组元素依次后移,并返回新数组长度 Array.unshif(value1, value2, value3, …);

移除数组第一个值,并返回该元素值 Array.shift();

在任意位置添加或删除元素

删除:可以删除任意数量的项,只需指定2个参数:要删除的第一项的位置和要删除的项数。例如splice(0,2)会删除数组中的前两项。

插入:可以向指定位置插入任意数量的项,只需提供3 个参数:起始位置、0(要删除的项数)和要插入的项。如果要插入多个项,可以再传入第四、第五,以至任意多个项。例如splice(2,0,"red","green")会从当前数组的位置2 开始插入字符串"red"和"green"。

替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定3 个参数:起始位置、要删除的项数和要插入的任意数量的项。插入的项数不必与删除的项数相等。例如splice (2,1,"red","green")会删除当前数组位置2的项,然后再从位置2开始插入字符串"red"和"green"。

var colors = ["red", "green", "blue"];
var removed = colors.splice(0,1); // 删除第一项
alert(colors); // green,blue
alert(removed); // red,返回的数组中只包含一项

removed = colors.splice(1, 0, "yellow", "orange"); // 从位置1 开始插入两项
alert(colors); // green,yellow,orange,blue
alert(removed); // 返回的是一个空数组

removed = colors.splice(1, 1, "red", "purple"); // 插入两项,删除一项
alert(colors); // green,red,purple,orange,blue
alert(removed); // yellow,返回的数组中只包含一项

合并

在没有给concat()方法传递参数的情况下,它只是复制当前数组并返回副本。如果传递给concat()方法的是一或多个数组,则该方法会将这些数组中的每一项都添加到结果数组中。如果传递的值不是数组,这些值就会被简单地添加到结果数组的末尾。下面来看一个例子。
Array.concat(x);

重排序

reverse()和sort()方法的返回值是经过排序之后的数组。

颠倒顺序 Array.reverse()

排序 Array.sort(function(num1,num2){ return num1 - num2; })

位置方法

indexOf()和lastIndexOf()这两个方法都接收两个参数:要查找的项和表示查找起点位置的索引(可选)。其中indexOf()方法从数组的开头(位置0)开始向后查找,lastIndexOf()方法则从数组的末尾开始向前查找。

var numbers = [1,2,3,4,5,2,3,4,5];
console.log(numbers.indexOf(4)); //3
console.log(numbers.lastIndexOf(4)); //7
console.log(numbers.indexOf(9)); //-1

迭代方法

这五个迭代函数的特点是都有一个 callback 函数,函数会为每一个数组元素调用一次 callback 函数。

  1. every():对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true。
  2. some():对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true。
  3. filter():对数组中的每一项运行给定函数,返回该函数会返回true 的项组成的数组。
  4. forEach():对数组中的每一项运行给定函数。这个方法没有返回值。
  5. map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。

可选参数是 thisArg, 作为 callback被调用时的 this 值,如果没有传入 thisArg 值,则在非严格模式下将会是全局对象,严格模式下是 undefined。其中,callback 函数中包含三个参数,分别是当前元素的值、当前元素索引和被遍历的数组。这 5 种函数遍历的元素个数在第一次调用 callback 函数时就已经确定,即以后即使添加元素也不会改变遍历次数,未访问到且被删除的值不会被 callback 访问到,未访问到且被修改的元素被修改后,传递给 callback 的值是被修改后的值。

every()和some(),不同之处在于函数返回项如果都为true那么every()才返回true,只有一项为true那么some()就返回ture

var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item, index, array){
    return (item > 2);
});
alert(everyResult); //false

var someResult = numbers.some(function(item, index, array){
    return (item > 2);
});
alert(someResult); //true

filter()返回符合条件的数组

var numbers = [1,2,3,4,5,4,3,2,1];
var filterResult = numbers.filter(function(item, index, array){
    return (item > 2);
});
alert(filterResult); //[3,4,5,4,3]

map()返回的数组,是对数组的每一项都是在原始数组中的对应项上运行传入函数的结果

var numbers = [1,2,3,4,5,4,3,2,1];
var mapResult = numbers.map(function(item, index, array){
    return item * 2;
});
alert(mapResult); //[2,4,6,8,10,8,6,4,2]

forEach()没有返回值,直接在其数组上操作

var numbers = [1,2,3,4,5,4,3,2,1];
numbers.forEach(function(item, index, array){
    //do something
});

归并方法

reduce()和reduceRight()两个方法都会迭代数组的所有项,然后构建一个最终返回的值。其中,reduce()方法从数组的第一项开始,逐个遍历到最后。而reduceRight()则从数组的最后一项开始,向前遍历到第一项。
cllaback函数的四个参数含义

// previousValue:上一次执行 callback 函数后返回的值
// currentValue:当前数组元素值
// index:当前数组元素索引
// array:遍历的数组对象
Array.reduce(function(previousValue, currentValue, index, array){
    // do something
}, [initialValue]);

第一次调用 callback 函数时,如果 initialValue 有值,则 previousValue 为 initialValue,currentValue 为数组第一个元素。否则 previousValue 为数组第一个元素,currentValue 为数组第二个元素。

ES6 API

Array.from()将一个类数组对象或可迭代对象转换成真实的数组。

let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']

entries()keys()values() 用于遍历数组

for (let index of ['a', 'b'].keys()) {
  console.log(index);
}
// 0
// 1

for (let elem of ['a', 'b'].values()) {
  console.log(elem);
}
// 'a'
// 'b'

for (let [index, elem] of ['a', 'b'].entries()) {
  console.log(index, elem);
}
// 0 "a"
// 1 "b"

更多 ES6 数组扩展方法参考这里

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant