如何按对象的日期属性排序及首个JS代码片段运行原理详解
问题背景
现有三个实现日期分组的代码片段:
- 专业人士提供的代码片段1
- 我编写的代码片段2
- 使用underscore.js实现的代码片段3
我想了解第一个代码片段的运行逻辑,它在比对两个日期时是如何正确按日期顺序添加元素的?
前置方法说明:
unshift()方法会向数组开头添加新元素,返回新增元素后的数组长度splice()方法可对数组进行元素添加或移除操作,返回被移除的元素集合
代码片段1运行逻辑详解
1. 排序预处理
首先调用underscore的_.sortBy(obj, "dt")将原始数组按dt日期字段从小到大排序,得到的顺序为Jan 21, 2021的元素在前,Jan 22次之,Jan 23的元素在最后;随后调用reverse()将数组整体倒序,遍历顺序变为从最新日期Jan 23到最早日期Jan 21。
2. 遍历插入逻辑
维护两个空数组:keyHolder用来记录已经处理过的日期,keyedObj用来存放最终的分组结果。
遍历排序后的每个元素时:
- 先取当前元素的
dt日期值,检查keyHolder中是否存在该日期:如果不存在,说明是第一次处理这个日期,就往keyedObj的开头插入日期分组标题{"day": 当前日期},同时将该日期存入keyHolder的开头做标记。 - 无论是否是新日期,都调用
keyedObj.splice(1, 0, 当前元素),把当前元素插入到keyedObj的索引1位置。
3. 顺序实现原理
因为遍历是从最新日期往最早日期走,每次碰到新的更早的日期,都会把该日期的分组标题插到整个结果数组的最开头,最终所有日期分组就会按从早到晚的顺序排列;而同日期的元素每次都插入到当前分组标题的后面位置,所以同日期下的元素会保持原始倒序后的排列顺序。
完整代码片段
代码片段1
var obj = [{"name":"ris", "id":3, "dt": "Jan 23, 2021"}, {"name":"rsi", "id":4, "dt": "Jan 23, 2021"}, {"name":"isr", "id":5, "dt": "Jan 22, 2021"}, {"name":"rsi", "id":6, "dt": "Jan 22, 2021"}, {"name":"isr", "id":7, "dt": "Jan 21, 2021"}, {"name":"rsi", "id":8, "dt": "Jan 21, 2021"}]; var keyHolder = []; var keyedObj = []; obj = _.sortBy(obj, "dt"); obj = obj.reverse(); obj.forEach((m) => { var formattedDate = m.dt; if(keyHolder.indexOf(formattedDate) == -1){ keyedObj.unshift({"day": formattedDate}); keyHolder.unshift(formattedDate); } keyedObj.splice(1,0, m); }); console.log(keyedObj);
依赖引入:
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.1/underscore-min.js"></script>
代码片段2
var obj = [{"name":"ris", "id":3, "dt": "Jan 23, 2021"}, {"name":"sri", "id":4, "dt": "Jan 23, 2021"}, {"name":"isr", "id":5, "dt": "Jan 22, 2021"}, {"name":"rsi", "id":6, "dt": "Jan 22, 2021"}, {"name":"isr", "id":7, "dt": "Jan 21, 2021"}, {"name":"rsi", "id":8, "dt": "Jan 21, 2021"}]; var dates = obj.map((dt) => dt.dt).filter((value, index, self) => self.indexOf(value) === index); dates.reverse(); const orderByDate = Object.fromEntries( dates.map(function(dt){ var filteredObj = obj.filter((d) => d.dt === dt); return [dt, filteredObj ]; })); console.log(orderByDate);
代码片段3
var obj = [{"name":"ris", "id":3, "dt": "Jan 23, 2021"}, {"name":"rsi", "id":4, "dt": "Jan 23, 2021"}, {"name":"isr", "id":5, "dt": "Jan 22, 2021"}, {"name":"rsi", "id":6, "dt": "Jan 22, 2021"}, {"name":"isr", "id":7, "dt": "Jan 21, 2021"}, {"name":"rsi", "id":8, "dt": "Jan 21, 2021"}]; const sortedByDate = _.groupBy(obj, "dt"); console.log(sortedByDate);
依赖引入:
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.1/underscore-min.js"></script>
内容的提问来源于stack exchange,提问作者SagitSri
相关产品推荐
相关产品推荐

