【发布时间】:2021-02-21 14:18:17
【问题描述】:
我不太熟悉在 Javascript 中对数组和对象进行排序,我想知道在某些条件下如何对对象进行排序。 最终目标是在日历函数中使用这种排序。
举个例子,假设我们有类似下面的 sn-p 的情况:
$(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>
让我们不再关注如何将数据放入数组或对象中,而是关注将数据排序为正确顺序/格式的过程。
| 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 |
在获取数据时,它们按上述顺序显示,但由于用户可以移动和扩展/缩小每个元素,因此我需要相应地设置事件 div 的 z-index 以用于样式设置。
也就是说一旦元素定位完成,原始数据按照上面的数据,我需要按照以下条件对数据进行排序:
- 最早的开始日期为first。
- 如果 2 个元素具有相同的开始日期,则持续时间较长的元素优先于另一个元素
按照这个逻辑,上面的结果应该按照以下顺序结束
| 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 |
我已经用一个工作示例更新了 sn-p,但如果有更好的方法来完成同样的事情,请告诉我。
/C
【问题讨论】:
-
向我们展示您的尝试。 SO 不是免费的代码编写服务。此处的目的是让您发布解决自己问题的尝试,并在其他人无法按预期工作时提供帮助。见How to Ask和minimal reproducible example
-
明白了!我会在睡觉后发布我的尝试!
-
我已经用代码的工作副本更新了我的 sn-p,但仍然想知道是否有更好的方法来编写代码。非常感谢任何反馈。
-
如果您的比较器在“diff”值相同时没有返回一致的结果,您的排序将产生不可预知的结果。如果多次比较数组中的两个元素,则无法保证它们会以相同的顺序进行比较。
-
另外,如果“diff”值是一个数字,你可以直接返回
b.diff - a.diff,这样就可以解决问题了。
标签: javascript arrays sorting jquery-multisortable