当数组具有布尔值时,哪种排序方法最好?
Which is the best way to sort an array when it has boolean values?
我正在上一门课程,当我到达挑战部分时,老师要求写下一个代码来对这个对象数组进行排序,其中包含一些 'todos' 具有以下属性:'text, and completed (boolean)'
排序应该是这样的:未完成的待办事项 (false) 应该排在第一位,已完成的待办事项应该排在最后。
我写下了一个代码,它确实有效并按要求对数组进行了排序,但是当我看到讲师如何解决这个挑战时,我有点困惑,因为他使用了不同的方式,所以我想在互联网上询问哪一个(我的代码或讲师的)是最好的,也更准确。
我实际上很困惑,因为我的代码有效,但是我只给 sort() 函数一个参数或参数 (a),它按照我的需要对数组进行了排序,所以我需要一个解释
这是基本对象数组:
// The basic objects array:
const todos = [{
text: 'wake up',
completed: true
}, {
text: 'get some food',
completed: false
}, {
text: 'play csgo',
completed: false
}, {
text: 'play minecraft',
completed: true
}, {
text: 'learn javascript',
completed: false
}];
这是我写的代码:
// My code
let sortTodos = function(todos) {
todos.sort(function(a) {
if (a.completed === false) {
return -1;
}
else if (a.completed === true){
return 1;
}
else {
return 0;
}
})
}
sortTodos(todos);
console.log(todos);
教师代码
// The instructor's code
const sortTodos = function (todos) {
todos.sort(function (a, b) {
if (!a.completed && b.completed) {
return -1
} else if (!b.completed && a.completed) {
return 1
} else {
return 0
}
})
}
输出是:
[ { text: 'get some food', completed: false },
{ text: 'play csgo', completed: false },
{ text: 'learn javascript', completed: false },
{ text: 'play minecraft', completed: true },
{ text: 'wake up', completed: true } ]
虽然 sort
通常 应该 使用两个参数,但您的代码恰好可以工作,因为正如您的逻辑所示,您只需要检查其中一个参数的值正在比较的项目,因为您只是将数组排序为两个部分,其中完成的部分排在第一位。如果你知道一个被比较的对象是否完成,就足以知道它应该在另一个被比较的对象之前还是之后,不管另一个对象是什么。
也就是说,虽然使用这样的算法是 可能的 ,但它很奇怪且令人困惑 - 最好根据 completed
属性 中的差异明确排序在被比较的两个对象中:
const todos = [{
text: 'wake up',
completed: true
}, {
text: 'get some food',
completed: false
}, {
text: 'play csgo',
completed: false
}, {
text: 'play minecraft',
completed: true
}, {
text: 'learn javascript',
completed: false
}];
todos.sort((a, b) => a.completed - b.completed);
console.log(todos);
如果你想要更少的计算复杂度,你可以在 O(n)
时间而不是 O(n log n)
时间很容易地做到这一点,只需将数组分成两部分并将它们放回一起:
const todos = [{
text: 'wake up',
completed: true
}, {
text: 'get some food',
completed: false
}, {
text: 'play csgo',
completed: false
}, {
text: 'play minecraft',
completed: true
}, {
text: 'learn javascript',
completed: false
}];
const trues = [];
const falses = [];
todos.forEach((obj) => {
(obj.completed ? trues : falses).push(obj);
});
console.log([...falses, ...trues]);
我正在上一门课程,当我到达挑战部分时,老师要求写下一个代码来对这个对象数组进行排序,其中包含一些 'todos' 具有以下属性:'text, and completed (boolean)' 排序应该是这样的:未完成的待办事项 (false) 应该排在第一位,已完成的待办事项应该排在最后。 我写下了一个代码,它确实有效并按要求对数组进行了排序,但是当我看到讲师如何解决这个挑战时,我有点困惑,因为他使用了不同的方式,所以我想在互联网上询问哪一个(我的代码或讲师的)是最好的,也更准确。 我实际上很困惑,因为我的代码有效,但是我只给 sort() 函数一个参数或参数 (a),它按照我的需要对数组进行了排序,所以我需要一个解释
这是基本对象数组:
// The basic objects array:
const todos = [{
text: 'wake up',
completed: true
}, {
text: 'get some food',
completed: false
}, {
text: 'play csgo',
completed: false
}, {
text: 'play minecraft',
completed: true
}, {
text: 'learn javascript',
completed: false
}];
这是我写的代码:
// My code
let sortTodos = function(todos) {
todos.sort(function(a) {
if (a.completed === false) {
return -1;
}
else if (a.completed === true){
return 1;
}
else {
return 0;
}
})
}
sortTodos(todos);
console.log(todos);
教师代码
// The instructor's code
const sortTodos = function (todos) {
todos.sort(function (a, b) {
if (!a.completed && b.completed) {
return -1
} else if (!b.completed && a.completed) {
return 1
} else {
return 0
}
})
}
输出是:
[ { text: 'get some food', completed: false },
{ text: 'play csgo', completed: false },
{ text: 'learn javascript', completed: false },
{ text: 'play minecraft', completed: true },
{ text: 'wake up', completed: true } ]
虽然 sort
通常 应该 使用两个参数,但您的代码恰好可以工作,因为正如您的逻辑所示,您只需要检查其中一个参数的值正在比较的项目,因为您只是将数组排序为两个部分,其中完成的部分排在第一位。如果你知道一个被比较的对象是否完成,就足以知道它应该在另一个被比较的对象之前还是之后,不管另一个对象是什么。
也就是说,虽然使用这样的算法是 可能的 ,但它很奇怪且令人困惑 - 最好根据 completed
属性 中的差异明确排序在被比较的两个对象中:
const todos = [{
text: 'wake up',
completed: true
}, {
text: 'get some food',
completed: false
}, {
text: 'play csgo',
completed: false
}, {
text: 'play minecraft',
completed: true
}, {
text: 'learn javascript',
completed: false
}];
todos.sort((a, b) => a.completed - b.completed);
console.log(todos);
如果你想要更少的计算复杂度,你可以在 O(n)
时间而不是 O(n log n)
时间很容易地做到这一点,只需将数组分成两部分并将它们放回一起:
const todos = [{
text: 'wake up',
completed: true
}, {
text: 'get some food',
completed: false
}, {
text: 'play csgo',
completed: false
}, {
text: 'play minecraft',
completed: true
}, {
text: 'learn javascript',
completed: false
}];
const trues = [];
const falses = [];
todos.forEach((obj) => {
(obj.completed ? trues : falses).push(obj);
});
console.log([...falses, ...trues]);