简体   繁体   English

javascript 关于使用时间戳对数组进行排序的问题

[英]javascript question about sorting array with timestamps

I am not that familiar with sorting arrays and objects within Javascript and are wondering about how you would sort out objects after certain conditions.我对排序 arrays 和 Javascript 中的对象不太熟悉,并且想知道在某些条件下如何对对象进行排序。 The end goal is use this sorting in a calendar function.最终目标是在日历 function 中使用这种排序。

So as an example let's say we have a situation like the snippet below:举个例子,假设我们有一个类似下面代码片段的情况:

 $(document).on('mouseup', '.event', function(){ var box_date = $(this).attr('date'); var param = []; $(`.day[date=${box_date}].event`).each(function(){ var box = $(this); var row = {}; var time_start = box.attr('time_start'); var time_end = box.attr('time_end'); var id_event = box.attr('id_event'); var time_diff = timeDiff(time_start, time_end); row.time_start = time_start; row.time_end = time_end; row.diff = time_diff; row.id_event = id_event; param.push(row); }) console.log(param); param.sort((a, b) => { if (a.time_start < b.time_start){ return -1; } else if (a.time_start > b.time_start){ return 1; } else if (b.diff - a.diff) return -1; return 1; }); console.log(param); }) function timeDiff(time_start, time_end){ var today = new Date(), month = today.getMonth() + 1, day = today.getDate(), year = today.getFullYear(); month = month.toString(); month = month.padStart(2,'0'); day = day.toString(); day = day.padStart(2, '0'); date = [year, month, day].join('-'); var date1 = `${date} ${time_start}`; var date2 = `${date} ${time_end}`; date1 = new Date(date1); date2 = new Date(date2); var diff_time = Math.abs(date1 - date2); // convert the time diff from ms to min diff_time = diff_time / (1000 * 60); return diff_time; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="day" date="2021-02-21"> <div class="event" id_event="1" date="2021-02-21" time_start="10:00" time_end="10:30">Val1</div> <div class="event" id_event="2" date="2021-02-21" time_start="10:00" time_end="11:00">Val2</div> <div class="event" id_event="3" date="2021-02-21" time_start="10:00" time_end="12:00">Val3</div> <div class="event" id_event="4" date="2021-02-21" time_start="09:30" time_end="12:00">Val4</div> <div class="event" id_event="5" date="2021-02-21" time_start="13:00" time_end="15:00">Val5</div> </div>

Let's just not focus on how to get the data into arrays or object but rather the process of sorting the data into the right order / format.让我们不要关注如何将数据放入 arrays 或 object 中,而是关注将数据排序为正确顺序/格式的过程。

event id事件编号 date日期 time start时间开始 time end时间结束 minutes分钟
1 1 2021-02-21 2021-02-21 10:00 10:00 10:30 10:30 30 30
2 2 2021-02-21 2021-02-21 10:00 10:00 11:00 11:00 60 60
3 3 2021-02-21 2021-02-21 10:00 10:00 12:00 12:00 120 120
4 4 2021-02-21 2021-02-21 09:30 09:30 12:00 12:00 150 150
5 5 2021-02-21 2021-02-21 13:00 13:00 15:00 15:00 120 120

When fetching the data they appear as in the order above but since each and every element both can be moved and extended / reduced by the user, I need to set the z-index of the event divs accordingly for styling purposes.获取数据时,它们按上述顺序显示,但由于用户可以移动和扩展/缩小每个元素,因此我需要相应地设置事件 div 的 z-index 以进行样式设置。

That means that once the positioning of the elements are done and the original data is according to the data above, I need to sort the data according with the following conditions:这意味着一旦元素的定位完成并且原始数据根据上面的数据,我需要根据以下条件对数据进行排序:

  1. The earliest start date as first.最早的开始日期为第一个。
  2. If 2 elements have the same start date, the one with longer duration has precedence over the other one如果 2 个元素具有相同的开始日期,则持续时间较长的元素优先于另一个元素

By following that logic the above result should end up following the following order通过遵循该逻辑,上述结果应遵循以下顺序

event id事件编号 date日期 time start时间开始 time end时间结束 minutes分钟
4 4 2021-02-21 2021-02-21 09:30 09:30 12:00 12:00 150 150
3 3 2021-02-21 2021-02-21 10:00 10:00 12:00 12:00 120 120
2 2 2021-02-21 2021-02-21 10:00 10:00 11:00 11:00 60 60
1 1 2021-02-21 2021-02-21 10:00 10:00 10:30 10:30 30 30
5 5 2021-02-21 2021-02-21 13:00 13:00 15:00 15:00 120 120

I've updated the snippet with a working example, but if there are better ways of accomplishing the same thing, please let me know.我已经用一个工作示例更新了片段,但如果有更好的方法来完成同样的事情,请告诉我。

/C /C

You can do the same thing as you would with SQL.您可以执行与 SQL 相同的操作。

FROM events
ORDER BY time_start ASC, time_end DESC

In JavaScript this can be done in the following manner:在 JavaScript 中,这可以通过以下方式完成:

events.sort((a, b) => {
  // time_start ascending
  if (a.time_start < b.time_start) return -1;
  if (a.time_start > b.time_start) return  1;
  // time_end descending
  if (a.time_end < b.time_end) return  1;
  if (a.time_end > b.time_end) return -1;
  // equal
  return 0;
});

Note that this is based on character comparison, which works because your times are zero padded and in the 24h notation.请注意,这是基于字符比较的,因为您的时间是零填充的,并且是 24 小时制。 This fails for the time 4:20 which should be 04:20 .这在4:20应该是04:20的时间失败。 Without the 0 in front it will be considered later than for example 12:42 because 4 (code 0x34) > 1 (code 0x31) (first characters).如果没有前面的0 ,它将被认为于例如12:42 ,因为4 (code 0x34) > 1 (code 0x31) (第一个字符)。

I've also added a more descriptive option, but this does introduce some helper functions.我还添加了一个更具描述性的选项,但这确实引入了一些辅助函数。

 $(document).on('mouseup', '.event', function(){ var box_date = $(this).attr('date'); var param = []; $(`.day[date=${box_date}].event`).each(function(){ var box = $(this); var row = {}; var time_start = box.attr('time_start'); var time_end = box.attr('time_end'); var id_event = box.attr('id_event'); row.time_start = time_start; row.time_end = time_end; row.id_event = id_event; param.push(row); }) console.log(param); param.sort((a, b) => { // time_start ascending if (a.time_start < b.time_start) return -1; if (a.time_start > b.time_start) return 1; // time_end descending if (a.time_end < b.time_end) return 1; if (a.time_end > b.time_end) return -1; // equal return 0; }); console.log(param); // or if you don't mind introducing some helpers param.sort(asc(event => event.time_start).chain(desc(event => event.time_end))); console.log(param); }) // helpers function asc(mapFn) { return attachComparatorMethods(function (a, b) { a = mapFn(a); b = mapFn(b); return -(a < b) || +(a > b); }); } function desc(mapFn) { const comparator = asc(mapFn); return attachComparatorMethods(function (a, b) { return comparator(b, a); }); } function attachComparatorMethods(comparator) { return Object.assign(comparator, { chain(comparator) { return attachComparatorMethods((a, b) => this(a, b) || comparator(a, b)); } }); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="day" date="2021-02-21"> <div class="event" id_event="1" date="2021-02-21" time_start="10:00" time_end="10:30">Val1</div> <div class="event" id_event="2" date="2021-02-21" time_start="10:00" time_end="11:00">Val2</div> <div class="event" id_event="3" date="2021-02-21" time_start="10:00" time_end="12:00">Val3</div> <div class="event" id_event="4" date="2021-02-21" time_start="09:30" time_end="12:00">Val4</div> <div class="event" id_event="5" date="2021-02-21" time_start="13:00" time_end="15:00">Val5</div> </div>

If you have issues understanding the asc helper, it is probably due to the line:如果您在理解asc帮助程序时遇到问题,可能是由于以下行:

return -(a < b) || +(a > b);

Which could also be written as:也可以写成:

if (a < b) return -1;
if (a > b) return  1;
return 0;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM