2012-11-22 40 views
0

我对我正在处理的项目有要求,这对我来说有点棘手。通过分析这些字符串中的日期详细信息对字符串数组进行排序

基本上我有排序基于这些项目的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服务返回的,我无法更改文本。所以我必须照原样处理。

+0

我最近刚刚在PHP中有类似的问题,我发现PHP函数'sscanf'的组合和'strtotime'很有帮助。由于有一些将PHP函数移植到Javascript的实用程序,因此也可能有一个端口。 - 编辑:发现这里的东西:http://phpjs.org/functions/sscanf/&http://phpjs.org/functions/strtotime/ – Paul

+0

呃,你应该真的存储时间戳,并使用这种日期格式仅用于显示 – Bergi

回答

2

您可以使用解析值出来的文字和描述here他们在数字上比较自定义排序功能。

var answers = [ 
    { Id: 1, Text: '3-4 weeks ago' }, 
    { Id: 2, Text: '1-2 weeks ago' }, 
    { Id: 3, Text: '7-8 weeks ago' }, 
    { Id: 4, Text: '5-6 weeks ago' }, 
    { Id: 5, Text: '1-2 days ago' }, 
    { Id: 6, Text: 'More than 1 month ago' } 
]; 

answers.sort(function(a, b) { 
    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); 
    } 
    return(getVal(b) - getVal(a)); 
}); 

工作演示:http://jsfiddle.net/jfriend00/cf3D7/

可以很明显的微调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); 
    }); 
})() 

附:请注意我在jsFiddle中使用的效率更高的数组声明语法。

+0

你要么使用String.prototype.contains,要么将索引与'-1'比较:-)另外,将getVal放在比较函数之外应该会提高性能 – Bergi

+0

@Bergi - 我更正了'indexOf()比较。如果数组很大,我还添加了关于性能预计算排序索引的说明。 – jfriend00

+0

@ jfriend00非常好,非常感谢。让我在我的项目中尝试一下。我现在需要弹出,但当我回来时会检查它。看起来非常棒。 –

0

在我看来,一个好办法,用的indexOf()方法和搜索每个元素的数组单词,像月,日,星期等..然后使用后的indexOf搜索数字。要提取文本,您可以使用子字符串。例如字符串'1-2周前',你会说str.substring(0,indexOf' - '),这样会得到从第一个字符到破折号的所有内容。所以你会提取他的第一个数字,即使它是3或4位数字。(你也可能抓住' - '字符,所以它可能必须是indexOf(' - ') - 1 ..研究那。)

一个很好的方法来做到这一点,搜索阵列的最大单位如果没有找到任何东西,寻找月份等。然后有一个临时数组,并复制所有包含你正在寻找的时间单位的元素。因此对于您的示例,您可以搜索多年,找不到,搜索几个月,查找包含单词月份的1个元素,然后将其移至临时数组中。那么你会分析你的临时数组中的所有元素,并找到最大数字的元素。所以在你的例子的情况下,你只能有一个,但你的回答看起来像

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个元素以月份单位放入新的排序数组中。然后,你会看到几周,你会发现有四个星期的元素,将它们移到临时数组中,分析它们中的数字,按大小排序,然后将它们粘贴在已排序的数组中,然后移动到天等。

HTP有点反正

相关问题