[英]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 ![]() |
2021-02-21 ![]() |
10:00 ![]() |
10:30 ![]() |
30 ![]() |
2 ![]() |
2021-02-21 ![]() |
10:00 ![]() |
11:00 ![]() |
60 ![]() |
3 ![]() |
2021-02-21 ![]() |
10:00 ![]() |
12:00 ![]() |
120 ![]() |
4 ![]() |
2021-02-21 ![]() |
09:30 ![]() |
12:00 ![]() |
150 ![]() |
5 ![]() |
2021-02-21 ![]() |
13:00 ![]() |
15:00 ![]() |
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:这意味着一旦元素的定位完成并且原始数据根据上面的数据,我需要根据以下条件对数据进行排序:
By following that logic the above result should end up following the following order通过遵循该逻辑,上述结果应遵循以下顺序
event id![]() |
date![]() |
time start![]() |
time end![]() |
minutes![]() |
---|---|---|---|---|
4 ![]() |
2021-02-21 ![]() |
09:30 ![]() |
12:00 ![]() |
150 ![]() |
3 ![]() |
2021-02-21 ![]() |
10:00 ![]() |
12:00 ![]() |
120 ![]() |
2 ![]() |
2021-02-21 ![]() |
10:00 ![]() |
11:00 ![]() |
60 ![]() |
1 ![]() |
2021-02-21 ![]() |
10:00 ![]() |
10:30 ![]() |
30 ![]() |
5 ![]() |
2021-02-21 ![]() |
13:00 ![]() |
15:00 ![]() |
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.