如何首先按数据排序json数据然后按时间排序?

时间:2015-04-25 10:11:02

标签: javascript json

我有类似下面的json数据。我正在尝试使用以下代码对其进行排序

{
    id: "xxxx",
    feed_id: "yyyy",
    title: "abcd ",
    detail: "efgh.",
    event_date: "Tue, 26 May 2015 00:00:00 +1000",
    event_time: "6:30pm",
    date: "Thu, 23 Apr 2015 23:05:04 +1000",
    expires_at: 1432634400,
    end_time: "8:00pm",
    timestamp: 1429794304
},
{
    id: "xxxx",
    feed_id: "yyyy",
    title: "efgh",
    detail: "efgh.",
    event_date: "Tue, 26 May 2015 00:00:00 +1000",
    event_time: "4:30pm",
    date: "Thu, 23 Apr 2015 23:05:04 +1000",
    expires_at: 1432634400,
    end_time: "8:00pm",
    timestamp: 1429794304
},    {
    id: "xxxx",
    feed_id: "yyyy",
    title: "ijkl",
    detail: "efgh.",
    event_date: "Tue, 27 May 2015 00:00:00 +1000",
    event_time: "1:30pm",
    date: "Thu, 23 Apr 2015 23:05:04 +1000",
    expires_at: 1432634400,
    end_time: "8:00pm",
    timestamp: 1429794304
}

但问题是两个事件可以在相同的日期,但在不同的时间,这是json数据中的另一个元素,称为 event_time ,可以在相同的json数据上看到。

如何排序,首先按event_date进行排序,如果它们相等,则按各自的时间排序?

提前致谢?

{{1}}

6 个答案:

答案 0 :(得分:4)

这是一个简单的解决方案:

function comp(a, b) {
  var d1= new Date(a.event_date)*1,
      d2= new Date(b.event_date)*1,
      t1= new Date('1/1/1970 '+(a.event_time.replace(/(a|p)/i, ' $1')))*1,
      t2= new Date('1/1/1970 '+(b.event_time.replace(/(a|p)/i, ' $1')))*1;

  return (d1+t1)-(d2+t2);
} //comp

此代码:

  1. 在“pm”或“am”之前插入一个空格以使时间有效。
  2. 每次追加到1970年1月1日的日期并将其转换为日期。
  3. 使所有日期都为数字(自1970年1月1日以来的毫秒数)。
  4. 从a.event_date和a.event_time(作为日期)的总和中减去b.event_date和b.event_time(作为日期)的总和。
  5. 无论“pm”或“am”的情况如何,或者“pm”或“am”之前的空格数(0或更多)都可以。如果缺少“pm”或“am”,则假定为24小时的军事时间。

    Fiddle

答案 1 :(得分:3)

如果减去两个日期会导致0(无差异),请在等式中包含时间。类似的东西:



var result = document.querySelector('#result');
result.textContent = 
   JSON.stringify(getData().sort(sortDateTime), null, ' ') +
   '\n\n**using sortDateTime2\n'+
   JSON.stringify(getData().sort(sortDateTime2), null, ' ');



function sortDateTime(a, b) {
  var A = new Date(a.event_date);
  var B = new Date(b.event_date);
  if (A - B == 0) {
    // no difference, include event_time
    var tA = a.event_time.split(':');
    var tB = b.event_time.split(':');
    A.setHours( /pm/i.test(tA[1]) ? +tA[0]+12 : tA[0] );
    A.setMinutes(+tA[1].replace(/[a-z]/gi, ''));
    B.setHours(/pm/i.test(tB[1]) ? +tB[0]+12 : tB[0]);
    B.setMinutes(+tB[1].replace(/[a-z]/gi, ''));
  }
  return A - B;
}

// sorting on date/time using setTime helper
function sortDateTime2(a, b) {
  return setTime(new Date(a.event_date), a.event_time) - 
         setTime(new Date(b.event_date), b.event_time);
}

// bonus: helper to set time from a time string
function setTime(thisDate, timeStr) {
  return new Date(
           [ [ thisDate.getFullYear(), 
               thisDate.getMonth()+1, 
               thisDate.getDate() 
             ].join('/'),
             timeStr.replace(/(a|p)/, function (m) {return ' ' + m;} ) ]
             .join(' ')
  );
}

function getData() {
  return [{
     id: "xxxx",
     feed_id: "yyyy",
     title: "abcd ",
     detail: "efgh.",
     event_date: "Tue, 26 May 2015 00:00:00 +1000",
     event_time: "6:30pm",
     date: "Thu, 23 Apr 2015 23:05:04 +1000",
     expires_at: 1432634400,
     end_time: "8:00pm",
     timestamp: 1429794304
    },
    {
     id: "xxxx",
     feed_id: "yyyy",
     title: "abcd ",
     detail: "efgh.",
     event_date: "Tue, 26 May 2015 00:00:00 +1000",
     event_time: "4:30pm",
     date: "Thu, 23 Apr 2015 23:05:04 +1000",
     expires_at: 1432634400,
     end_time: "8:00pm",
     timestamp: 1429794304
    },    {
     id: "xxxx",
     feed_id: "yyyy",
     title: "abcd ",
     detail: "efgh.",
     event_date: "Tue, 27 May 2015 00:00:00 +1000",
     event_time: "1:30pm",
     date: "Thu, 23 Apr 2015 23:05:04 +1000",
     expires_at: 1432634400,
     end_time: "8:00pm",
     timestamp: 1429794304
    }
  ];
}

<pre id="result"></pre>
&#13;
&#13;
&#13;

答案 2 :(得分:2)

我不认为Date.parse适用于您的时间格式。你可以使用这样的东西:

&#13;
&#13;
function parseDateTime(d, t) {
  var date = new Date(d);
  var a = t.slice(-2);
  var t = +t.replace(/[apm:]/g, '');
  var h = ~~(t/100);
  var m = t%100;

  if(a == "pm" && h < 12) h += 12;
  if(a == "am" && h == 12) h -= 12;
  date.setHours(h);
  date.setMinutes(m);
  return date;
}

function comp(a, b) {
  var da = parseDateTime(a.event_date, a.event_time);
  var db = parseDateTime(b.event_date, b.event_time);

  return da - db;
}
&#13;
&#13;
&#13;

&#13;
&#13;
function parseTime(t) {
  var a = t.slice(-2);
  var t = +t.replace(/[apm:]/g, '');

  if(a == "pm" && ~~(t/100) < 12) t += 1200;
  if(a == "am" && ~~(t/100) == 12) t -= 1200;
  return t;
}

console.log(Date.parse('8:00pm'));
// NaN

console.log(parseTime('8:00am'));
console.log(parseTime('11:59am'));
console.log(parseTime('12:00pm'));
console.log(parseTime('12:01pm'));
// 800
// 1159
// 1200
// 1201

console.log(parseTime('8:00pm'));
console.log(parseTime('11:59pm'));
console.log(parseTime('12:00am'));
console.log(parseTime('12:01am'));
// 2000
// 2359
// 0
// 1
&#13;
&#13;
&#13;

答案 3 :(得分:1)

你可以用这个:

function comp(a, b) {
    // Compare dates
    if (new Date(a.event_date).getTime() != new Date(b.event_date).getTime())
        return new Date(a.event_date) - new Date(b.event_date);

    // If dates are equal, compare hours
    return Date.parse(a.event_time) - Date.parse(b.event_time);
}

data=data.sort(comp)  

修改 我添加了自定义日期解析器(受this启发)和字符串排序器。

function parseDate(dateString) {
    var d = new Date();
    var time = dateString.match(/(\d+)(?::(\d\d))?\s*(p?)/);
    d.setHours( parseInt(time[1]) + (time[3] ? 12 : 0) );
    d.setMinutes( parseInt(time[2]) || 0 );
    return d;
}

function comp(a, b) {
    // Compare dates
    if (new Date(a.event_date).getTime() != new Date(b.event_date).getTime())
        return new Date(a.event_date) - new Date(b.event_date);

    // If dates are equal, compare hours
    var hourA = parseDate(a.event_time);
    var hourB = parseDate(b.event_time);
    if (hourA.getTime() != hourB.getTime())
        return hourA - hourB;

    // If hours are equal, compare titles
    if(a.title > b.title)
        return -1;
    else
        return 1;
}

答案 4 :(得分:1)

您可以使用moment.jsevent_time

创建日期对象
var sortedJ = _j.sort(function(a,b){

    var result = new Date(a.event_date) - new Date(b.event_date);

    if(result === 0)
    {
        return new moment("01/01/2000 "+a.event_time,"MM/DD/YYYY h:mm:ss a") - moment("01/01/2000 "+b.event_time,"MM/DD/YYYY h:mm:ss a");
    }

    return result;
});

这是一个有效的JS FIDDLE

答案 5 :(得分:0)

你可以试试这个

function comp(a, b) {
    var diff = new Date(a.event_date) - new Date(b.event_date);
    if(diff < 0) return -1;
    else if(diff > 0) return 1;
    else if(parseTime(a.event_time) < parseTime(b.event_time)) return -1;
    else if(parseTime(a.event_time) > parseTime(b.event_time)) return 1;
    else return 0;
}

但为什么不将event_date和event_time设为一个属性?

编辑:

您还可以自己定义一个sortBy函数,以帮助您按任意数量的属性进行排序。

function sortBy(list, f) {
  list.sort(function(a, b) {
    var fa = f(a), fb = f(b);
    if(fa < fb) return -1;
    else if(fa > fb) return 1;
    else return 0;
  });
}

然后您可以按日期,时间和标题排序

sortBy(list, function(o) {
  return [new Date(o.event_date), parseTime(o.event_time), o.title];
});