JavaScript按可空布尔值排序数组,然后按字符串排序

JavaScript按可空布尔值排序数组,然后按字符串排序,javascript,arrays,sorting,object,Javascript,Arrays,Sorting,Object,我尝试对具有可空布尔值和标题的对象数组进行排序。如果列表中的某项被设置为重要项,“ReadUnderstand”为true或false,如果不是,则为null。如果“readUnderstanding”为true或null,我希望列表按字母顺序排列,但如果值为false,我希望它位于列表顶部 下面的代码最接近我想要的。这将按字母顺序返回列表,其中列表顶部的“ReadUnderstand”为false。但是“readUnderstand”为true的项目会在列表的末尾结束,而不是按字母顺序结束。任

我尝试对具有可空布尔值和标题的对象数组进行排序。如果列表中的某项被设置为重要项,
“ReadUnderstand”
true
false
,如果不是,则为
null
。如果
“readUnderstanding”
true
null
,我希望列表按字母顺序排列,但如果值为
false
,我希望它位于列表顶部

下面的代码最接近我想要的。这将按字母顺序返回列表,其中列表顶部的
“ReadUnderstand”
false
。但是
“readUnderstand”
true
的项目会在列表的末尾结束,而不是按字母顺序结束。任何帮助都将不胜感激

items = [
    {Title: 'A', ReadUnderstood: null},
    {Title: 'C', ReadUnderstood: false},
    {Title: 'E', ReadUnderstood: null},
    {Title: 'B', ReadUnderstood: true},
    {Title: 'D', ReadUnderstood: true},
    {Title: 'F', ReadUnderstood: null},
]

items.sort((a, b) => { 
    return (b.ReadUnderstood != null && b.ReadUnderstood == false) - (a.ReadUnderstood != null && a.ReadUnderstood == false) || a.Title - b.Title; 
})

Desired result:
items = [
    {Title: 'C', ReadUnderstood: false},
    {Title: 'A', ReadUnderstood: null},
    {Title: 'B', ReadUnderstood: true},
    {Title: 'D', ReadUnderstood: true},
    {Title: 'E', ReadUnderstood: null},
    {Title: 'F', ReadUnderstood: null},
]

您不能通过减去字符串来比较它们(减去非数字字符串将始终导致
NaN
)。
当涉及的操作数是数字(数字、布尔值等)时,只能使用
-
进行排序,否则将以错误的排序顺序结束

要比较字符串,可以使用
{
让AreaDunderstand=a.ReadUnderstand!==false;
让breadUnderstand=b.readUnderstand!==false;
if(区域停机位!==面包停机位)
返回区停机位-面包停机位;
其他的
返回a.Title.localeCompare(b.Title);
});
控制台日志(项目)您很接近了。应返回一个数字,并根据它是正、负还是零,正在比较的两个项目
(a、b)
相对移动。减去布尔值返回一个数字。所以,第一个条件很好。对于字符串,需要使用按字母顺序排序

此外,还可以简化第一个条件。您不需要检查
null
,也不需要对
false
进行严格的相等性检查

items.sort((a, b) => 
  (b.ReadUnderstood === false) - (a.ReadUnderstood === false) 
    || a.Title.localeCompare(b.Title)
)
下面是一个工作片段:

const项=[
{Title:'A',readUnderstanding:null},
{Title:'C',readUnderstanding:false},
{Title:'E',readUnderstanding:null},
{Title:'B',readUnderstanding:true},
{Title:'D',readUnderstanding:true},
{Title:'F',readUnderstanding:null},
]
项目排序((a,b)=>
(b.readUnderstand==false)-(a.readUnderstand==false)
||a.Title.localeCompare(b.Title)
)
console.log(项目)
试试

项目=[
{Title:'A',readUnderstanding:null},
{Title:'C',readUnderstanding:false},
{Title:'E',readUnderstanding:null},
{Title:'B',readUnderstanding:true},
{Title:'D',readUnderstanding:true},
{Title:'F',readUnderstanding:null},
]
items.sort((a,b)=>a.readUnderstanding==false?
-1:(b.readUnderstand==false?1:a.Title.localeCompare(b.Title));

控制台日志(项目)这里是另一个选项。首先根据
item.readUnderstanding==false
对数组进行分区。然后对两个数组进行排序并将它们重新连接在一起

Array.prototype.partition=函数(回调,thisArg){
if(thisArg!==未定义)callback=callback.bind(thisArg);
常量分区={true:[],false:[]};
this.forEach((item,…args)=>partitions[!!callback(item,…args)].push(item));
返回[partitions[true],partitions[false];
};
常数项=[
{Title:'A',readUnderstanding:null},
{Title:'C',readUnderstanding:false},
{Title:'E',readUnderstanding:null},
{Title:'B',readUnderstanding:true},
{Title:'D',readUnderstanding:true},
{Title:'F',readUnderstanding:null},
];
const[ruFalse,ruOther]=items.partition(item=>item.readUnderstanding==false);
constbytitle=({Title:t1},{Title:t2})=>t1.localeCompare(t2);

log(ruFalse.sort(byTitle).concat(ruOther.sort(byTitle))请添加输入样本和预期输出,以创建一个关于多个
false
值的示例。它们也需要按字母顺序排序吗?这也更可取,是:)您需要比较两个对象之间的
readUnderstanding
,否则排序将无法正常工作。当<代码> c>代码>项目是数组中的第一个项目时,您的排序将在中间某个地方排序,而不是在TopScript的一个例子中失败:几乎,也需要处理两个都是代码> false < /Cord>的情况,然后按字母顺序排序。e、 g.
C
在本例中应位于
g
之前:怪异。您的代码片段正在执行我想要的操作,但当我试图在代码中实现它时,列表只进行了排序alphabetically@Hammis82我在arrow函数中使用隐式返回。因为compareFunction中有
{}
,所以需要添加
return
我不知道一个布尔值可以减去/添加到另一个布尔值。每天学习一些东西。对于其他阅读:
true
表示
1
false
表示
0
true-false/=>1
@3limin4t0r展开“true代表1”:可以在javascript中减去任何内容。它们被强制为基于操作数的不同类型。在中,对2个操作数调用。从链接表中可以看到,“如果参数为true,结果为1。如果参数为false,结果为+0”。@3limin4t0r对于对象,
ToNumber
calls,方法。因此,如果覆盖对象的
valueOf
函数,则可以在算术运算中使用它们<代码>变量a={valueOf:()=>1};var b={valueOf:()=>2}
So,
b-a
返回
1
return a.Text.localeCompare(b.Text);
items.sort((a, b) => 
  (b.ReadUnderstood === false) - (a.ReadUnderstood === false) 
    || a.Title.localeCompare(b.Title)
)
items.sort((a,b) => a.ReadUnderstood===false ? 
  -1 : (b.ReadUnderstood===false ? 1 : a.Title.localeCompare(b.Title)));