微搭中的变量一共有文本、数字、布尔值、对象、数组几种。前三种对于新手来说还好理解一些,但是后边的两种就不是太好理解了,本篇我们讲解一下数组的常见用法。
1 创建数组
// 使用数组字面量
let fruits = ['apple', 'banana', 'orange'];
// 使用Array构造函数
let numbers = new Array(1, 2, 3, 4, 5);
一般我们常见的用法是通过中括号的语法来定义数组。当然了除了自己定义外,我们更多的是读取数据源的数据。在微搭中,我们使用查询多条获取到的数据,调用他的records属性的时候返回的就是一个数组
2 访问和修改数组元素
let colors = ['red', 'green', 'blue'];
console.log(colors[0]); // 输出: 'red'
colors[1] = 'yellow';
console.log(colors); // 输出: ['red', 'yellow', 'blue']
如果我们希望获取数组中的元素的,可以使用下标来获取。数组中的索引是从0开始的
3 数组长度
let animals = ['cat', 'dog', 'elephant'];
console.log(animals.length); // 输出: 3
如果想获取数组的长度,我们可以访问他的length属性,如果数组没有元素他会返回0
在鉴权的场景中,我们会根据当前小程序用户的openid去数据源获取数据,如果未匹配到数据,调用records的length属性就会返回0,我们就可以根据返回的结果来进行权限控制
4 添加和删除元素
let stack = [];
stack.push('a'); // 在末尾添加元素
stack.push('b', 'c'); // 可以一次添加多个元素
console.log(stack); // 输出: ['a', 'b', 'c']
let lastItem = stack.pop(); // 移除并返回最后一个元素
console.log(lastItem); // 输出: 'c'
console.log(stack); // 输出: ['a', 'b']
stack.unshift('x'); // 在开头添加元素
console.log(stack); // 输出: ['x', 'a', 'b']
let firstItem = stack.shift(); // 移除并返回第一个元素
console.log(firstItem); // 输出: 'x'
console.log(stack); // 输出: ['a', 'b']
可以调用push方法给数组添加元素,可以调用pop方法移除元素,不过要注意的是,不管是添加还是移除我们都是从数组的最后一个元素开始的。如果想从开始位置添加或者移除,我们就需要调用unshift和shift方法
5 遍历数组
let fruits = ['apple', 'banana', 'orange'];
// 使用for循环
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
// 使用for...of循环
for (let fruit of fruits) {
console.log(fruit);
}
// 使用forEach方法
fruits.forEach(fruit => console.log(fruit));
我们一共可以使用三种方法遍历数组的元素,第一种可以使用for循环,这种你可以通过数组的长度来进行循环,比如数组里是基本类型的,如文本、数字、布尔值。
第二种 for of循环,这种可以用来迭代数组中是对象的元素的,比如你要获取对象中的某个属性。更多的场景比如我们要读取数据源的数据,这个时候需要用到await关键字,那for of 循环就是一个不错的写法。而且for of不仅可以遍历数组,也可以遍历set 和map
遍历 set
// 创建一个 Set
let fruitsSet = new Set(['apple', 'banana', 'orange', 'apple']);
// 使用 for...of 遍历 Set
for (let fruit of fruitsSet) {
console.log(fruit);
}
// 输出:
// apple
// banana
// orange
// 如果需要索引,可以使用 entries() 方法
for (let [index, fruit] of [...fruitsSet].entries()) {
console.log(`${index}: ${fruit}`);
}
// 输出:
// 0: apple
// 1: banana
// 2: orange
遍历map
// 创建一个 Map
let fruitsMap = new Map([
['apple', 5],
['banana', 3],
['orange', 2]
]);
// 遍历键值对
for (let entry of fruitsMap) {
console.log(entry);
}
// 输出:
// ['apple', 5]
// ['banana', 3]
// ['orange', 2]
// 使用解构来分别获取键和值
for (let [fruit, quantity] of fruitsMap) {
console.log(`${fruit}: ${quantity}`);
}
// 输出:
// apple: 5
// banana: 3
// orange: 2
// 只遍历键
for (let fruit of fruitsMap.keys()) {
console.log(fruit);
}
// 输出:
// apple
// banana
// orange
// 只遍历值
for (let quantity of fruitsMap.values()) {
console.log(quantity);
}
// 输出:
// 5
// 3
// 2
第三种forEach,写起来比较简洁,我们可以用箭头函数来简化我们的代码,代码可读性更好,但是forEach不能使用break语句提前终止,适合一次性全部循环完毕的场景
6 数组的方法
let numbers = [1, 2, 3, 4, 5];
// map: 创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后的返回值
let doubled = numbers.map(num => num * 2);
console.log(doubled); // 输出: [2, 4, 6, 8, 10]
// filter: 创建一个新数组, 其包含通过所提供函数实现的测试的所有元素
let evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // 输出: [2, 4]
// reduce: 对数组中的每个元素执行一个由您提供的reducer函数,将其结果汇总为单个返回值
let sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 输出: 15
// find: 返回数组中满足提供的测试函数的第一个元素的值
let found = numbers.find(num => num > 3);
console.log(found); // 输出: 4
// some: 测试是否至少有一个元素通过由提供的函数实现的测试
let hasEven = numbers.some(num => num % 2 === 0);
console.log(hasEven); // 输出: true
// every: 测试一个数组内的所有元素是否都能通过某个指定函数的测试
let allPositive = numbers.every(num => num > 0);
console.log(allPositive); // 输出: true
let fruits = ['apple', 'banana', 'orange', 'mango', 'kiwi'];
let sliced = fruits.slice(1, 4);
console.log(sliced); // 输出: ['banana', 'orange', 'mango']
// 不指定结束索引会一直截取到数组末尾
let fromIndex2 = fruits.slice(2);
console.log(fromIndex2); // 输出: ['orange', 'mango', 'kiwi']
let colors = ['red', 'green', 'blue'];
colors.splice(1, 1, 'yellow', 'pink');
console.log(colors); // 输出: ['red', 'yellow', 'pink', 'blue']
// 只删除元素
colors.splice(2, 1);
console.log(colors); // 输出: ['red', 'yellow', 'blue']
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let combined = arr1.concat(arr2);
console.log(combined); // 输出: [1, 2, 3, 4, 5, 6]
// 可以连接多个数组
let arr3 = [7, 8, 9];
let multiCombined = arr1.concat(arr2, arr3);
console.log(multiCombined); // 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]
let elements = ['Fire', 'Air', 'Water'];
console.log(elements.join()); // 输出: "Fire,Air,Water"
console.log(elements.join(' ')); // 输出: "Fire Air Water"
console.log(elements.join('-')); // 输出: "Fire-Air-Water"
let numbers = [2, 5, 9, 2];
console.log(numbers.indexOf(2)); // 输出: 0
console.log(numbers.lastIndexOf(2)); // 输出: 3
console.log(numbers.indexOf(7)); // 输出: -1 (未找到)
let fruits = ['apple', 'banana', 'mango'];
console.log(fruits.includes('banana')); // 输出: true
console.log(fruits.includes('grape')); // 输出: false
let array = [1, 2, 3, 4, 5];
array.reverse();
console.log(array); // 输出: [5, 4, 3, 2, 1]
let fruits = ['banana', 'apple', 'orange', 'mango'];
fruits.sort();
console.log(fruits); // 输出: ['apple', 'banana', 'mango', 'orange']
// 使用比较函数进行数字排序
let numbers = [40, 100, 1, 5, 25, 10];
numbers.sort((a, b) => a - b);
console.log(numbers); // 输出: [1, 5, 10, 25, 40, 100]
let nestedArray = [1, [2, 3], [4, [5, 6]]];
console.log(nestedArray.flat()); // 输出: [1, 2, 3, 4, [5, 6]]
console.log(nestedArray.flat(2)); // 输出: [1, 2, 3, 4, 5, 6]
let numbers = [5, 12, 8, 130, 44];
let index = numbers.findIndex(num => num > 13);
console.log(index); // 输出: 3
熟练的掌握这些常见的方法,在你编写业务逻辑的时候往往问题就会迎刃而解
7 常见的场景
我们在编程的时候会有一些常见的场景用到数组的各种知识点
数组去重
let array = [1, 2, 2, 3, 4, 4, 5];
let uniqueArray = [...new Set(array)];
console.log(uniqueArray); // 输出: [1, 2, 3, 4, 5]
let array = [1, 2, 2, 3, 4, 4, 5];
let uniqueArray = array.filter((item, index, arr) => arr.indexOf(item) === index);
console.log(uniqueArray); // 输出: [1, 2, 3, 4, 5]
let array = [1, 2, 2, 3, 4, 4, 5];
let uniqueArray = array.reduce((unique, item) =>
unique.includes(item) ? unique : [...unique, item], []);
console.log(uniqueArray); // 输出: [1, 2, 3, 4, 5]
let array = [1, 2, 2, 3, 4, 4, 5];
let uniqueArray = [];
let seen = {};
array.forEach(item => {
if (!seen[item]) {
seen[item] = true;
uniqueArray.push(item);
}
});
console.log(uniqueArray); // 输出: [1, 2, 3, 4, 5]
let array = [1, 2, 2, 3, 4, 4, 5];
let uniqueArray = Array.from(new Set(array));
console.log(uniqueArray); // 输出: [1, 2, 3, 4, 5]
数组随机排序
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
let arr = [1, 2, 3, 4, 5];
console.log(shuffleArray(arr));
let arr = [1, 2, 3, 4, 5];
arr.sort(() => Math.random() - 0.5);
console.log(arr);
function shuffleArray(array) {
let shuffled = [];
let copy = [...array];
while (copy.length) {
let index = Math.floor(Math.random() * copy.length);
shuffled.push(copy.splice(index, 1)[0]);
}
return shuffled;
}
let arr = [1, 2, 3, 4, 5];
console.log(shuffleArray(arr));
数组扁平化(将多维数组转为一维)
// 使用 flat() 方法(ES2019)
let nestedArray = [1, [2, 3], [4, [5, 6]]];
let flatArray = nestedArray.flat(Infinity);
console.log(flatArray); // 输出: [1, 2, 3, 4, 5, 6]
// 递归方法(兼容旧版浏览器)
function flattenArray(arr) {
return arr.reduce((flat, toFlatten) =>
flat.concat(Array.isArray(toFlatten) ? flattenArray(toFlatten) : toFlatten), []);
}
查找数组中的最大值和最小值
let numbers = [5, 2, 8, 1, 9];
let max = Math.max(...numbers);
let min = Math.min(...numbers);
console.log(max, min); // 输出: 9 1
移除数组中的假值(false, null, 0, “”, undefined, NaN)
let array = [0, 1, false, 2, '', 3, null, undefined, NaN];
let filteredArray = array.filter(Boolean);
console.log(filteredArray); // 输出: [1, 2, 3]
数组分块(将数组分割成指定大小的小数组)
function chunkArray(array, size) {
return Array.from({ length: Math.ceil(array.length / size) }, (v, i) =>
array.slice(i * size, i * size + size)
);
}
let numbers = [1, 2, 3, 4, 5, 6, 7];
console.log(chunkArray(numbers, 3)); // 输出: [[1, 2, 3], [4, 5, 6], [7]]
数组交集(找出两个数组中的共同元素)
let arr1 = [1, 2, 3, 4, 5];
let arr2 = [3, 4, 5, 6, 7];
let intersection = arr1.filter(x => arr2.includes(x));
console.log(intersection); // 输出: [3, 4, 5]
数组差集(找出第一个数组中存在但第二个数组中不存在的元素)
let arr1 = [1, 2, 3, 4, 5];
let arr2 = [3, 4, 5, 6, 7];
let difference = arr1.filter(x => !arr2.includes(x));
console.log(difference); // 输出: [1, 2]
从数组中随机选择元素
function getRandomElement(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
let fruits = ['apple', 'banana', 'orange', 'grape'];
console.log(getRandomElement(fruits)); // 随机输出一个水果
数组去重并保持原有顺序
function uniqueInOrder(arr) {
return arr.filter((item, index) => arr.indexOf(item) === index);
}
let array = [1, 2, 2, 3, 4, 4, 5, 3];
console.log(uniqueInOrder(array)); // 输出: [1, 2, 3, 4, 5]
计算数组中元素出现的次数
let fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
let count = fruits.reduce((acc, fruit) => {
acc[fruit] = (acc[fruit] || 0) + 1;
return acc;
}, {});
console.log(count); // 输出: { apple: 3, banana: 2, orange: 1 }
总结
日常和粉丝交流的时候,经常会有一句话,我是零基础的,我一看到代码就发憷。其实这就和小学生第一次拿到课本,感到发怵一样。你不认字就要读文章,背古诗本身就是不现实的事情。我们即使使用低代码工具也是要求你基本功扎实,基本功就是要先熟悉概念,多实践,在实践中积累经验就好了。无他,唯手熟尔。