排序一直有很多的算法,今天我们仅仅来说JavaScript内置的排序方法
● 字符串
const owners = ['Jonas', 'Zach', 'Adam', 'Martha'];
console.log(owners.sort());
console.log(owners);
但是注意,这个方法会改变原有的数组;
● 我们在试试数字
console.log(movements);
console.log(movements.sort());
这并没有按照我们的想法来从大到小排序,因为这个方法仅仅是针对字符串的,所以这些数字也是先转换字符串然后再进行排序的,这个时候我们就需要传入一个回调函数来实现这样的排序
movements.sort((a, b) => {
if (a > b) return 1;
if (a < b) return -1;
});
console.log(movements);
这样就被很好的进行排序了,那么这个到底是怎么工作的呢?
这段代码是使用JavaScript的Array.prototype.sort()方法对数组movements进行排序。解释一下代码的工作原理:
- Array.prototype.sort()方法是一个原地排序算法,它会修改原始数组,并返回排序后的数组。该方法接受一个比较函数作为参数,用于确定元素的顺序。
- 比较函数(a, b) => {…}会被传递给sort()方法,它接受两个参数a和b,分别表示数组中的两个元素。
- 在比较函数中,通过比较a和b的值来确定它们的顺序。如果a小于b,则返回一个负数(例如-1),表示a应该排在b之前;如果a大于b,则返回一个正数(例如1),表示a应该排在b之后;如果a等于b,则返回0,表示它们的顺序相同。
- sort()方法根据比较函数返回的值对数组进行排序。如果比较函数返回负数,则a会在b之前,如果返回正数,则a会在b之后,如果返回0,则它们的相对位置不变。
按照上面说明的原理,从大到小排序的话我们就可以这么写:
movements.sort((a, b) => {
if (a < b) return 1;
if (a > b) return -1;
});
console.log(movements);
● 上面那个只是想演示原理,实际只需要下面写就可以了,只需要关系返回的是正数和复数即可
movements.sort((a, b) => a - b);
console.log(movements);
movements.sort((a, b) => b - a);
console.log(movements);
你只需要记得,如果返回正数的话,就a>b,b在a前面,所以就是从小到大排序,反之亦然
● 那么现在让我们回到应用程序上面去,通过应用程序的按钮来是的用户的movments进行排序
const displayMovements = function (movements, sort = false) {
containerMovements.innerHTML = '';
const movs = sort ? movements.slice().sort((a, b) => a - b) : movements;
movs.forEach((mov, i) => {
const type = mov > 0 ? 'deposit' : 'withdrawal';
const html = `
<div class="movements__row">
<div class="movements__type movements__type--${type}">${
i + 1
} ${type}</div>
<div class="movements__value">${mov}€</div>
</div>`;
containerMovements.insertAdjacentHTML('afterbegin', html);
});
};
首先我们先这个函数修改,传入一个sort参数,默认的值为flase,后面我们通过这个sort值来确定你是要进行排序还是不进行排序;
之后我们写一个一个movs变量,如果sort值为ture的话,对数据进行渐层拷贝,防止对原始数据产生影响,,然后再对拷贝后的数据进行一个降序排序,如果sort为false的话就直接使用未排序的movments数组;
● 完成上面之后,我们就对其进行一个点击事件,当我们点击的时候就进行排序
btnSort.addEventListener('click', function (e) {
e.preventDefault();
displayMovements(currentAccount.movements, true);
});
● 这个通过点击事件使用,来修改sort的值来进行排序,但是当我们再次点击sort按钮时,并不会回复数组的排序,还是进行从小到大排序,这个事情就需要我们来设置一个状态变量
let sorted = false;
btnSort.addEventListener('click', function (e) {
e.preventDefault();
displayMovements(currentAccount.movements, !sorted);
sorted = !sorted;
});
因为首先设置为false,点击时候,进行取反,就是true,就会继续排序,然后通过sorted = !sorted取反,下次再点击的是就是false了