我正在努力解决Wes Bos Javascript 30的数组有氧运动挑战,并且正在努力理解sort()函数在一起运行或顺序运行时的行为。
我们从一系列发明者对象开始,最初的挑战是按生日排序。
初始函数(orderBirth)按计划工作,并返回按预期排序的数组。
然后,我们编写另一个函数(最旧的)以按发明人的年龄对发明人数组进行排序。再次按预期工作。
但是,如果我重新运行console.log(orderBirth),它将返回按年龄而不是生日排序的数组。
我知道sort函数会更改原始数组(对其进行突变),但我不明白为什么这样做会阻止orderBirth函数在第二次运行时正常工作。
const inventors = [
{ first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
{ first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
{ first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
{ first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
{ first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
{ first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
{ first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
{ first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
{ first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
{ first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
{ first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
{ first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
];
const orderBirth = inventors.sort((a, b) => a.year > b.year ? 1 : -1);
console.log('Ordered by birthdate table')
console.log(orderBirth)
const oldest = inventors.sort((a, b) => {
const lastInventor = a.passed - a.year;
const nextInventor = b.passed - b.year;
return lastInventor > nextInventor ? -1 : 1;
});
console.log('Ordered by age')
console.log(oldest);
console.log('Re-running orderBirth gives unexpected result')
console.log(orderBirth)
我已经阅读了does-sort-function-change-original-array的帖子,但这虽然解释了sort函数的就地变异,但并不能回答我的问题。或者至少它不能用我目前对JS的理解水平来回答。
答案 0 :(得分:1)
Sort改变了原始数组。因此,当您顺序使用sort时,最终将一次又一次地更改同一数组。
let arr = [1,2,3,5,6,64,76,52]
arr.sort((a,b)=> a-b)
console.log(arr)
您可以创建数组副本,然后对其进行排序
let arr = [1,2,3,5,6,64,76,52]
let arr2 = [...arr].sort((a,b)=> a-b)
console.log(arr,arr2)
答案 1 :(得分:1)
在JS中,数组名称仅存储对原始数组的引用。然后对数组进行排序(更改)。您没有使用
复制数组const orderBirth = investors.sort((a,b)=> a.year> b.year?1:-1);
相反,您要存储对按年份排序的数组的引用。
当您再次使用其他功能进行排序时,主数组将更改。而且orderBirth仍指向它。因此,情况也会发生变化。
编辑:如Scorpioo590所说,.slice()方法将复制该数组。
const orderBirth = creator.slice()。sort((a,b)=> a.year> b.year?1:-1);
以这种方式正确实现了您假设'='运算符的操作。
答案 2 :(得分:1)
sort
使原始数组变异并返回排序后的数组。因此,它们都指向内存中的同一阵列。这两个都将返回true
:
console.log(inventors === orderBirth)
console.log(oldest === orderBirth)
const inventors=[{first:'Albert',last:'Einstein',year:1879,passed:1955},{first:'Isaac',last:'Newton',year:1643,passed:1727},{first:'Galileo',last:'Galilei',year:1564,passed:1642},{first:'Marie',last:'Curie',year:1867,passed:1934},{first:'Johannes',last:'Kepler',year:1571,passed:1630},{first:'Nicolaus',last:'Copernicus',year:1473,passed:1543},{first:'Max',last:'Planck',year:1858,passed:1947},{first:'Katherine',last:'Blodgett',year:1898,passed:1979},{first:'Ada',last:'Lovelace',year:1815,passed:1852},{first:'Sarah E.',last:'Goode',year:1855,passed:1905},{first:'Lise',last:'Meitner',year:1878,passed:1968},{first:'Hanna',last:'Hammarström',year:1829,passed:1909}]
const orderBirth = inventors.sort((a, b) => a.year > b.year ? 1 : -1);
const oldest = inventors.sort((a, b) => {
const lastInventor = a.passed - a.year;
const nextInventor = b.passed - b.year;
return lastInventor > nextInventor ? -1 : 1;
});
console.log(inventors === orderBirth)
console.log(oldest === orderBirth)
答案 3 :(得分:1)
正如您提到的,sort函数会更改原始数组。
有
const orderBirth = inventors.sort(...)
得到数组的引用。这意味着两个变量实际上都指向内存中的同一位置。因此,在更改原始数组时,您还更改新变量。
您将需要创建原始数组的副本以保留排序结果。
const orderBirth = inventors.sort(...).slice();
应该可以解决问题。