当数组具有布尔值时,哪种排序方法最好?

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]);