在对象数组中将空值排序到最后

5

我有一个对象数组,如下所示:

c = [{a: null}, {a: 12}, {a: 1}, {a: 50}, {a: 2}, {a: null}]

我希望你能将它们按照具有值的对象和没有值的对象分类排序。

我尝试的方法是:

c.sort(function(b) { return b.a ? -1 : 1 })

输出

[{a: 2}, {a: 50}, {a: 1}, {a: 12}, {a: null}, {a: null}]

预期输出

[{a: 12}, {a: 1}, {a: 50}, {a: 2}, {a: null}, {a: null}]

我该如何实现这个呢?

@GokulanPH 是的,我可以。只是在我的问题中没有使用它,所以没有标记它。 - Abhi
1
Array#sort 函数的 arity 为 2,它有 ab 参数用于比较。 - Xotic750
此外,要注意排序的稳定性:https://dev59.com/lHI_5IYBdhLWcg3wHvQ5 - Xotic750
8个回答

7
这将把null和其他假值放到列表末尾:

c = [{a: null}, {a: 12}, {a: 1}, {a: 50}, {a: 2}, {a: null}];
c.sort((x, y) => !!y.a - !!x.a);

console.log(c);

不过,由于你并没有真正地进行任何排序操作,你可以将列表分成两部分并重新连接它们:

c = [{a: null}, {a: 12}, {a: 1}, {a: 50}, {a: 2}, {a: null}];

r = [
  ...c.filter(x => x.a !== null),
  ...c.filter(x => x.a === null)
]

console.log(r)

这也不依赖于 sort 函数的稳定性。

1
它将零值移动到底部。 - Nina Scholz
在这种情况下,filter选项比使用sort要好得多,它避免了任何稳定性问题。 - Xotic750

3
您可以测试该值。如果值为null,则取比较的差值。

var c = [{ a: null }, { a: 12 }, { a: 1 }, { a: 50 }, { a: 2 }, { a: null }];

c.sort(function (a, b) {
    return (a.a === null) - (b.a === null);
});

console.log(c);
.as-console-wrapper { max-height: 100% !important; top: 0; }

如果要进行稳定排序,您可以使用带映射的排序,并将索引作为第二个排序选项。

// the array to be sorted
var list = [{ a: null }, { a: 12 }, { a: 1 }, { a: 50 }, { a: 2 }, { a: null }];

// temporary array holds objects with position and sort-value
var mapped = list.map(function(el, i) {
    return { index: i, value: el.a === null};
});

// sorting the mapped array containing the reduced values
mapped.sort(function(a, b) {
    return a.value - b.value || a.index - b.index;
});

// container for the resulting order
var result = mapped.map(function(el){
    return list[el.index];
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


很棒的解决方案 - Jan Ciołek

1

const c = [{a: null}, {a: 12}, {a: 1}, {a: 50}, {a: 2}, {a: null}];

let result = [...c.filter(_=>_["a"]!==null),...c.filter(_=>_["a"]===null)];

console.log(result);


1

尽管@Xotic750的评论“Array#sort函数的arity为2,它有一个a和b参数用于比较。”是正确的,但这个答案对我起作用了。 - Abhi
也许我看错了,但在 Edge 中,我看到顶部有一个空值,底部也有一个。它非常依赖于仅对两个值之间的一侧进行比较。 - Nina Scholz
1
@vsr,问题还是一样的。 - Nina Scholz

1

尝试使用return !a.a - !b.a。有效对象先出现。

var c = [{a: null}, {a: 12}, {a: 1}, {a: 50}, {a: 2}, {a: null}];

c.sort(function (a, b) {
    return !a.a - !b.a
});
console.log(c);


1
那样的方式?
c=[{a: null}, {a: 12}, {a: 1}, {a: 50}, {a: 2}, {a: null}];
c.sort(function(a,b){ return a.a===null ? 1:-1 })
console.log(c);

编辑

这将对对象进行排序,我只想将具有空值的对象推到最后。 - Abhi

0

它不是完美的,但仍然有效,干杯!

var c = [{a: null}, {a: 12}, {a: 1}, {a: 50}, {a: 2}, {a: null}]

c.sort(function(object1,object2){

  
  if(object1.a === null && object2.a !== null){return 1}
  
  if([object1.a,object2.a].every((a)=>a === null) ||      
     [object1.a,object2.a].every((a)=>a !== null)
     ){return 0}
  
  if(object1.a !== null && object2.a === null){return -1}
  


})

console.log(c);


0
这是一个关于按日期排序并将空值放在末尾(如果有)的案例:
userSortList = users.sort((a, b) => {
    if (b.lastConnectionDate === null || a.lastConnectionDate) {
        return -1
    } else {
        return (
            new Date(b.lastConnectionDate) - new Date(a.lastConnectionDate)
        )
    }
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接