开发中常用的数组操作方法
前端开发中,数据处理是必不可少的一件事情,而且往往操作最多的数据类型-数组,下面来讲讲那些数据中都有哪些操作技巧。
一、复制数组(深拷贝和浅拷贝)
如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。
先说浅拷贝:
//浅拷贝 let a = [1, 2, 3, 4]; let b = a; console.log(a === b); // => true b.push(5); console.log(a); // => [1, 2, 3, 4, 5]
深拷贝:
//深拷贝 let c = [1, 2, 3, 4]; let d = c.slice(); console.log(c === d); // => false d.push(t); console.log(c); // => [1, 2, 3, 4]
二、检查一个对象是否为数组
//检查对象是否是数组 let numbers = [1, 2, 3, 4]; let strs = 'hello, world'; console.log(Array.isArray(numbers)); //=> true console.log(Array.isArray(strs)); //=> false //instanceof console.log(numbers instanceof Array); //=> true console.log(strs instanceof Array); //=> false //构造方法检查 console.log(numbers.constructor == Array); //=> true console.log(strs.constructor == Array); //=> true
三、删除数组里的指定一项
将项目添加到数组很容易,但是没有内置的等效项可以删除你添加的项目。您需要依靠indexOf和splice、delete关键字来创建自己的删除功能:
//删除一个指定元素 let eventNumbers = [1, 2, 3, 4, 5, 6, 7, 8]; //splice实现 eventNumbers.splice(eventNumbers.indexOf(7), 1); console.log(eventNumbers); // => [1, 2, 3, 4, 5, 6, 8] //delete实现 let eventNumbers2 = [1, 2, 3, 4, 5, 6, 7, 8]; delete eventNumbers2[eventNumbers2.indexOf(7)]; console.log(eventNumbers2); // => [1, 2, 3, 4, 5, 6, empty, 8] console.log(eventNumbers2.length); // => 8
使用delete关键字发生的唯一事情是,已删除项设置为空值,但数组长度是不变的。
四、清空数组
要清空并删除数组中的所有内容,最简单的方法(也是最快的方法!)是使用完全不直观的方法,将数组的length属性设置为0:
/清空一个数组 let ary1 = ['苹果', '香蕉', '橘子']; ary1.length = 0; console.log(ary1); // => [] console.log(ary1.length); // => 0
五、数组去重
使用ES6和Set对象,从数组中删除重复的值非常简单:
//数组去重 let names = ["张三", "李四", "王五", "王五", "六六"]; let uniqueNames = [...new Set(names)]; console.log(uniqueNames); // => ["张三", "李四", "王五", "六六"]
诀窍是使用Spread(...)运算符,该运算符将项目集合扩展为单个项目。
六、数组排序
JavaScript中的数组带有一个方便的内置排序方法(sort),该方法使你可以精确指定排序方式。看下面的示例,在该示例中我们对一些数字和字符串进行排序:
//数组排序 let numbers2 = [3, 10, 2, 14, 7, 2, 9, 5]; let beatles = ["Ringo", "George", "Paul", "John"]; numbers2.sort(compareValues); beatles.sort(compareValues); function compareValues(a, b) { if (a < b) { // 如果a小于b return -1; } else if (a > b) { // 如果a大于b return 1; } else { // a = b return 0; } } console.log(numbers2); // => [2, 2, 3, 5, 7, 9, 10, 14] console.log(beatles); // => ["George", "John", "Paul", "Ringo"]
七、随机排列
如果要随机重新排列数组的所有内容,在数组的原型上添加方法:
//随机排序 Array.prototype.shuffle = function () { let input = this; for (let i = input.length - 1; i >= 0; i--) { let randomIndex = Math.floor(Math.random() * (i + 1)); let itemAtIndex = input[randomIndex]; input[randomIndex] = input[i]; input[i] = itemAtIndex; } return input; } let tempArray = [1, 2, 3, 4, 5, 6, 7, 8, 9]; console.log(tempArray.shuffle()); // => [6, 7, 3, 1, 4, 8, 9, 2, 5] console.log(tempArray.shuffle()); // => [6, 7, 3, 1, 4, 8, 9, 2, 5]
这个方法以后用在颜色渲染列表中应该是个不错的选择。
八、随机抽取一个元素
如果需要从我们的数组中随机选择一个元素,我们可以结合“随机数”的一些概念,并将其应用于以数组为中心的世界。该代码段将是:
//随机抽取一个元素 let myArray = ["书籍", "手机", "电脑", "平板"]; console.log(myArray[Math.floor(Math.random() * myArray.length)]); // => 电脑 console.log(myArray[Math.floor(Math.random() * myArray.length)]); // => 平板 console.log(myArray[Math.floor(Math.random() * myArray.length)]); // => 手机
哈哈哈,这玩意用在抽奖上可是妥妥的,不过这是会重复的。
九、合并数组
这个我记得前面单独拿了一个章节来讲这个,里面有很多种很全面的方法,有兴趣的朋友可以去翻一翻。
//数组合并 let smileys = ["😀", "😇", "😛", "🥶"]; let foods = ["🍊", "🥦", "🍔", "🍕", "🍰"]; let animals = ["🐙", "🐝", "🐈"]; let combined = [...smileys, ...foods, ...animals]; console.log(combined); // => ["😀", "😇", "😛", "🥶", "🍊", "🥦", "🍔", "🍕", "🍰", "🐙", "🐝", "🐈"]
十、元素交换
参考的是冒泡排序的方法,用来做两个元素交换。
//元素交换 let myData = ["a", "b", "c", "d", "e", "f", "g"]; let temp = myData[2]; myData[2] = myData[5]; myData[5] = temp; console.log(myData); // => ["a", "b", "f", "d", "e", "c", "g"]
十一、数组转JSON对象
原始数组项的索引位置将为键,而相应数组项的内容将为值。
//数组转json let airportCodes = ["SFO", "LAX", "SEA", "NYC", "ORD", "ATL"]; let airportCodesObject = { ...airportCodes }; console.log(airportCodesObject); // => {0: "SFO", 1: "LAX", 2: "SEA", 3: "NYC", 4: "ORD", 5: "ATL"}
十二、反转数组
利用数组的reverse来实现:
//reverse 反转数组 let numbers3 = [1, 2, 3, 4, 5, 6]; numbers.reverse(); console.log(numbers); // => [4, 3, 2, 1]
这个操作是在原来的数组上进行的,如果我们想数组进行反转之后,输出到一个新数组,可以这样来:
//返回一个新数组 let numbers4 = [1, 2, 3, 4, 5, 6]; let reversed = [...numbers4].reverse(); console.log(numbers4); // => [1, 2, 3, 4, 5, 6] console.log(reversed); // => [6, 5, 4, 3, 2, 1]
由此可见,原数组并不受影响。
十三、检查数组元素满足某种条件
来做个测试,利用数组的every方法来检查数组中的元素是否都满足偶数:
//判断满足偶数条件 let someNumbers = [2, 4, 38, 20, 10, 13, 42]; function isEven(currentItem) { if (currentItem % 2 === 0) { return true; } } console.log(someNumbers.every(isEven)); // => false
every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供);
十四、检查某些元素满足条件
上面一点讲了要所有元素满足条件才为真,那么这里用some 方法来检查只有某个元素达到条件,就为真:
//部分条件满足 let highScores = [46, 191, 38, 10, 156]; function isReallyHighScore(currentItem) { if (currentItem > 100) { return true; } } console.log(highScores.some(isReallyHighScore)); // => true
some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。
十五、数组降维
对宇宙观有了解的朋友应该都知道什么是降维打击,很经典的降维打击,出自中国科幻作家刘慈欣的经典作品《三体》一书,是指外星人使用“二向箔”将太阳系由三维空间降至二维空间的一种攻击方式。
那么在数组中,有一维数组、二维数组,三维数组...甚至到n纬数组,如果要把三维数组、二维数组转为一维数组,可以这么操作:
//数组降维 let cool = [1, 2, [1, 2, [1, 2]]]; // console.log(cool.flat(1)); // => [1, 2, 1, 2, [1, 2]] // console.log(cool.flat(2)); // => [1, 2, 1, 2, 1, 2]
在此示例中,我们的cool数组具有两个嵌套数组级别。通过将深度值指定为1,我们告诉 flat 方法将数组平整一层,仅保留一层嵌套数组,指定为2,将数组中2层嵌套都降为一维数组。
有时你想完全降为一维数组,因此你可以为深度指定一个较大的数值。如果你不知道数组嵌套的深度,则可以舍弃该深度的最终值以展平任何深度的任何数组:
//n纬打击 let cool2 = [1, 2, [[[[[1]]]], 2, [1, 2]]]; let flatCool = cool2.flat(Infinity); console.log(flatCool); // => [1, 2, 1, 2, 1, 2]
你可以为flat方法指定Infinity的深度值,这将确保数组在所有情况下都是一维数组显示的。
最后
其实编程也就是万变不离其宗,上面讲的这些或许不一定每样都用得上,但是,当你见过,有印象,为你以后在编程提供了思路也是很不错的。