【问题标题】:Which is the best way to sort an array when it has boolean values?当数组具有布尔值时,对数组进行排序的最佳方法是什么?
【发布时间】:2019-12-29 10:19:56
【问题描述】:

我正在学习一门课程,当我到达挑战部分时,老师要求写下一个代码,该代码对该对象数组进行排序,该数组包含一些具有以下属性的“待办事项”:“文本和已完成(布尔值)” 并且排序应该是这样的:未完成的 todos (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 } ]

【问题讨论】:

  • IMO 你可以简单地做到这一点const final = todos.sort((a,b)=>a.completed - b.completed)

标签: javascript arrays sorting boolean boolean-expression


【解决方案1】:

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

【讨论】:

  • 感谢您的解释,现在我知道为什么我的代码能正常工作了,非常感谢
  • 请注意,如果排序后的数组需要有超过 2 个块(一个在顶部,一个在底部) - 例如,排序属性可能在数字上是 0, 1, 2,如果你使用.sort 对它们进行排序,您需要使用.sort 中的两个参数,因为(例如)如果要比较的对象是1,您需要知道另一个对象是0还是2才能正确排序
  • 感谢您帮我解决这个问题,现在我可以完成课程了。
猜你喜欢
  • 2021-08-28
  • 2011-11-27
  • 2010-09-07
  • 1970-01-01
  • 2012-03-05
  • 2010-09-06
  • 1970-01-01
  • 2017-05-23
  • 2017-12-27
相关资源
最近更新 更多