当属性不一致时,如何根据属性对JS对象列表进行排序
How to sort a JS object list based on a property when the property is not consistent
我有一个包含各种对象的列表。这个列表中的一些对象有一个日期字段(它基本上是从服务器以字符串的形式返回给我的,而不是日期对象),而对于其他对象,这个字段是空的。
我的要求是在顶部显示没有日期的对象,而那些有日期的对象需要按日期字段排序后显示。
对于没有日期的对象,也需要按字母顺序进行排序。
早些时候我使用
$scope.lists.sort(function (a, b) {
return new Date(a.date.split("-")[2], a.date.split("-")[1], a.date.split("-")[0]) - new Date(b.date.split("-")[2], b.date.split("-")[1], b.date.split("-")[0]);
});
但现在有了空日期字段,这就不起作用了。所以找不到任何东西,我写了这样的逻辑:
{
var datelists=[];
var savelists =[];
$scope.lists.forEach(function (t) {
if (t.date !== null) {
datelists.push(t);
} else {
savelists.push(t);
}
});
datelists.sort(function (a, b) {
return new Date(a.date.split("-")[2], a.date.split("-")[1], a.date.split("-")[0]) - new Date(b.date.split("-")[2], b.date.split("-")[1], b.date.split("-")[0]);
});
savelists.sort(function (a, b) {
return a.name - b.name;
});
$scope.lists = [];
$scope.lists = savelists.concat(datelists);
}
我不喜欢这种冗长的方法。我相信有一种优雅的方法可以做到这一点。我想知道我还有什么其他选择?
为了避免拆分数组,请根据日期和文本的主键和辅键对整个数组进行排序。使用obj.date
和obj.text
作为分别包含日期和排序文本的示例属性名称:
function dateCompare( d, e)
{ // code to compare date strings
// return -1 for date d before e
// 0 for date d same as e
// +1 for date e before d
// algorithm depends on server date string format but could start
if( !d)
return e ? -1 : 0; // d is empty
if( !e)
return 1; // e is empty, d is not
// ... compare date strings
}
function textCompare(s, t)
{ // code to compare string values
// return -1 for s < t
// 0 for s == t
// +1 for t > s
// algorithms vary according to requirements.
}
function objCompare( a, b)
{ // return a non zero result of dateCompare, or the result of textCompare:
return dateCompare(a.date, b.date) || textCompare( a.text, b.text);
}
$scope.lists.sort( objCompare);
概述了如何在不涉及应用程序细节的情况下进行此操作。根据需要,将objCompare
转换为具有嵌套日期和文本比较支持函数(或内联代码)的内联匿名函数,以匹配现有编程风格。
排序时,必须检查日期是否为空、是否为undefined
或是否为正常日期(未测试)
.sort(function (a, b) {
// sort alphabetically
if (typeof a.date == 'undefined' && typeof b.date != 'undefined') {
return -1;
} else if (typeof a.date != 'undefined' && typeof b.date == 'undefined') {
return 1;
} else if (typeof a.date == 'undefined' && typeof b.date == 'undefined') {
return a.name.localeCompare(b.name);
// move null to top
} else if (a.date == null && b.date != null) {
return -1;
} else if (a.date != null && b.date == null) {
return 1;
} else if (a.date == null && b.date == null) {
return 0;
// both objects has date, sort by date.
} else {
var d1 = Date.parse(a.date);
var d2 = Date.parse(b.date);
return d1 - d2;
}
})
首先,您可以将date
转换为ISO6801日期字符串。
如果提供了date
,或者用空字符串替换了一个错误的值,则可以使用string#localeCompare。这会将空字符串排序到顶部。
如果日期相同或两者都没有日期,则按name
排序。
$scope.lists.sort(function (a, b) {
function date(s) {
return s.replace(/('d{2})-('d{2})-('d{4})/g, '$3-$2-$1');
}
return (date(a.date) || '').localeCompare(date(b.date) || '') ||
a.name.localeCompare(b.name);
});
相关文章:
- 为什么我可以在Array属性对象中找到Javascript Array for Each方法
- 使用onclick调用属性对象函数
- 嵌套为..in 循环,列出多维对象的属性(对象)
- 动态属性对象 - JSON
- 在不使用隔离范围angularjs自定义指令的情况下获取属性对象
- 通过属性传递属性/对象.Javascript
- Javascript:属性/对象的类型
- 访问JSON中的属性(对象)
- 属性对象Javascript不是用Jquery Deferred设置的
- 无法读取属性'#<对象>'未定义的获取错误
- Twitter中多属性对象的子字符串匹配
- 无法设置'data'属性'对象'标记.(只IE8)
- 更新数据属性对象属性值
- 将属性对象的选定对象从原型推入数组
- 将单个属性对象字面量的数组转换为仅包含其值的数组的最佳方法
- 寻找一种更简单的方法来检查是否多个属性&对象中的方法是未定义的
- 主干模型:带有get方法的空属性,但在属性对象中
- 如何赋值给"text"someText"属性对象在动能js
- Angularjs的数据绑定与数据属性对象
- 如何将一个嵌套的javascript对象转换为只有一级属性对象