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