Javascript 通过分析字符串中的日期详细信息对字符串数组进行排序
我现在正在做的项目有一个要求,这对我来说有点棘手 基本上,我必须根据项目的Javascript 通过分析字符串中的日期详细信息对字符串数组进行排序,javascript,sorting,Javascript,Sorting,我现在正在做的项目有一个要求,这对我来说有点棘手 基本上,我必须根据项目的Text属性对项目数组进行排序: 以下是我的物品: var answers = [], answer1 = { Id: 1, Text: '3-4 weeks ago' }, answer2 = { Id: 2, Text: '1-2 weeks ago' }, answer3 = { Id: 3, Text: '7-8 weeks ago' }, answer4 = { Id: 4, Te
Text
属性对项目数组进行排序:
以下是我的物品:
var answers = [],
answer1 = { Id: 1, Text: '3-4 weeks ago' },
answer2 = { Id: 2, Text: '1-2 weeks ago' },
answer3 = { Id: 3, Text: '7-8 weeks ago' },
answer4 = { Id: 4, Text: '5-6 weeks ago' },
answer5 = { Id: 5, Text: '1-2 days ago' },
answer6 = { Id: 6, Text: 'More than 1 month ago' };
answers.push(answer1);
answers.push(answer2);
answers.push(answer3);
answers.push(answer4);
answers.push(answer5);
answers.push(answer6);
我需要分析每个项目的Text
属性,以便在排序后,数组如下所示:
answers[0] = { Id: 6, Text: 'More than 1 month ago' }
answers[1] = { Id: 3, Text: '7-8 weeks ago' }
answers[2] = { Id: 4, Text: '5-6 weeks ago' }
answers[3] = { Id: 1, Text: '3-4 weeks ago' }
answers[4] = { Id: 2, Text: '1-2 weeks ago' }
answers[5] = { Id: 5, Text: '1-2 days ago' }
逻辑是,日期越远,优先级越高,因此它应该首先出现在数组中。因此,“1-2天”比“7-8周”更不重要
因此,逻辑是,我需要提取数值,然后提取单位(例如天、周),然后根据这些细节对数组进行排序
老实说,我发现很难想出一个解决办法,我非常感谢任何帮助
编辑:
关于我正在处理的数据,它是从web服务返回的,我没有能力更改文本。因此,我必须按原样使用它。您可以使用自定义排序函数来解析文本中的值,并按所述进行数字比较 工作演示: 显然,您可以微调
getVal()
函数,以支持所需的任何解析逻辑
如果数组很大,可以通过预计算排序索引并将其存储在每个对象中使其性能更好,这样自定义排序函数就可以直接比较两个数字,而不是每次都重新计算。但是,数组中不到100项可能是不相关的
此外,还不清楚“1个多月前”和“7-8周”的分类方法。我当前的算法将“超过1个月前”视为1个月,但如果您有特定的规则,可以调整解析逻辑。拥有自定义排序函数后,排序逻辑的关键在于getVal()
函数的实现,您可以调整该函数以支持您想要支持的任何语法
这是一个预计算sortKey的版本,因此对于大型阵列性能更好:
(function() {
function getVal(item) {
var val;
// find first number
var match = item.Text.match(/\d+/);
if (match) {
val = parseInt(match[0], 10);
} else {
val = 10000; // set to very high number
}
if (item.Text.indexOf("More than") !== -1) {
++val;
}
if (item.Text.indexOf("week") !== -1) {
val *= 7;
} else if (item.Text.indexOf("month") !== -1) {
val *= 30;
}
return(val);
}
for (var i = 0, len = answers.length; i < len; i++) {
answers[i].sortKey = getVal(answers[i]);
}
answers.sort(function(a, b) {
return(b.sortKey - a.sortKey);
});
})()
(函数(){
函数getVal(项){
var-val;
//查找第一个号码
var match=item.Text.match(/\d+/);
如果(匹配){
val=parseInt(匹配[0],10);
}否则{
val=10000;//设置为非常高的数字
}
if(item.Text.indexOf(“超过”)!=-1){
++瓦尔;
}
如果(item.Text.indexOf(“周”)!=-1){
val*=7;
}else if(item.Text.indexOf(“月”)!=-1){
val*=30;
}
返回(val);
}
for(变量i=0,len=answers.length;i
注意,我在JSFIDLE中使用了更高效的数组声明语法。在我看来,使用indexOf()方法并在数组中的每个元素中搜索单词(如月、日、周等)是一种好方法。。然后使用indexOf搜索数字。要提取文本,可以使用子字符串。例如,对于字符串“1-2周前”,您会说str.substring(0,indexOf'-'),这样就可以得到从第一个字符到破折号的所有内容。所以你要提取第一个数字,即使是3或4位数字。(您可能还捕获了“-”字符,因此它可能必须是indexOf(“-”)-1..研究它。) 执行此操作的一个好方法是,在数组中搜索最大的时间单位。。查找任何带有“年”的内容,如果没有找到,则搜索几个月,等等。。然后创建一个临时数组,并复制包含当前正在查找的时间单位的所有元素。因此,对于您的示例,您需要搜索年、无、月,找到包含单词month(s)的1个元素,并将其移动到临时数组中。然后分析temp数组中的所有元素,并找到数字最大的元素。所以在你的例子中,你只有一个,但是你的答案看起来像
answer1 = { Id: 1, Text: '3-4 weeks ago' },
answer2 = { Id: 2, Text: '1-2 weeks ago' },
answer3 = { Id: 3, Text: '7-8 weeks ago' },
answer4 = { Id: 4, Text: '6 months ago' },
answer5 = { Id: 5, Text: '5-6 weeks ago' },
answer6 = { Id: 6, Text: '1-2 days ago' },
answer7 = { Id: 7, Text: ' 1 month ago' };
answer8 = { Id: 8, Text: ' 3 months ago' };
然后以月为单位有3个元素,然后查看所有3个元素,并根据数量进行排序,所以6个月、3个月、1个月。然后,为已排序的数组创建第三个也是最后一个数组,或者只是重新设置主数组的大小。我认为一个新的“排序”数组会更好。因此,您将这3个元素与月份单位一起放入新的排序数组中
然后你会转到weeks,你会找到带有weeks的4个元素,将它们移动到临时数组中,分析其中的数字,按大小排序,然后将它们粘贴到排序数组中,然后移动到days等
不管怎样,htp有点我最近在PHP中遇到了类似的问题,我发现PHP函数
sscanf
和strotime
的组合很有帮助。因为有一些实用程序将PHP函数移植到Javascript,所以也可能有一个用于该函数的端口。-编辑:在这里找到了一些东西:&嗯,您应该真正存储时间戳,并且只在显示时使用这种日期格式。您可以使用String.prototype.contains,或者将索引与-1
:-)进行比较。此外,将getVal
放在比较函数之外应该会使performant@Bergi-我更正了indexOf()
比较。我还添加了一个关于在数组较大时预计算排序索引以提高性能的说明。@jfriend00这太好了,非常感谢。让我在我的项目中尝试一下。我现在需要出去,但我回来后会去看看。看起来真的很棒。
answer1 = { Id: 1, Text: '3-4 weeks ago' },
answer2 = { Id: 2, Text: '1-2 weeks ago' },
answer3 = { Id: 3, Text: '7-8 weeks ago' },
answer4 = { Id: 4, Text: '6 months ago' },
answer5 = { Id: 5, Text: '5-6 weeks ago' },
answer6 = { Id: 6, Text: '1-2 days ago' },
answer7 = { Id: 7, Text: ' 1 month ago' };
answer8 = { Id: 8, Text: ' 3 months ago' };