多列排序-先a降序排序再按b升序排序,其中包含了排序信息-实现方法function multipleSort(data, sorts)

数据

let sort_data = [{
		a: 1,
		b: 'a'
	},
	{
		a: 2,
		b: 'b'
	},
	{
		a: 2,
		b: 'c'
	},
];
let sorts = [{
		key: 'a',
		order: 'desc'
	},
	{
		key: 'b',
		order: 'asc'
	},
];

排序后的结果

//结果 先a降序,再按b升序
[
	{a:2,b:'b'},
	{a:2,b:'c'},
	{a:1,b:'a'},
]

思路

* 本方法限定sorts第一个key对应的值为number,其他为string
* a排好序后,b在a的基础上进行排序,即对data中a值相同的数据进行再排序;c在b的基础上排序……  以sorts中的先后顺序为准
* a排好序后,获取a对应值相同的数据,并获取这些数据在data中的下标
* 使用slice截取下标对应的数据,并按b排好序
* splice替换slice排好序的数据

实现

function multipleSort(data, sorts) {
	let prevKey = '';
	sorts.forEach((val, idx) => {
		if (idx === 0) {
			data.sort((x, y) => val.order === 'desc' ? y[val.key] - x[val.key] : x[val.key] - y[val.key]);
		} else {
			reorder(val, prevKey, data);
		}
		// 上次排序的key
		prevKey = val.key;
	})
	return data;
};

/**
 * sort: 本次排序规则
 * prevKey: 上次排序key
 * data: 原始数据
 * */
function reorder(sort, prevKey, data) {
	let flag = false; // 是否是相同的数据标志
	let prevVal = ''; // 上次遍历key对应的val
	let idxArr = [];
	for (let i = 0; i < data.length; i++) {
		// 以上次排序规则为基础, 如果本次值和上次相同则idxArr新增一个[],放上次相同值的index, 本次的值index不放但标记出来:flag=true
		// 如果本次值和上次不同 ,在flag=true的条件下,放入上次的index, flag设为false
		if (data[i][prevKey] === prevVal) {
			if (!flag) idxArr.push([i - 1]);
			flag = true;
		} else {
			if (flag) {
				idxArr[idxArr.length - 1].push(i - 1);
				flag = false;
			}
		}
		prevVal = data[i][prevKey];
	}

	// 排序替换
	idxArr.forEach((idxVal, idx) => {
		const needOrderArr = data.slice(idxVal[0], idxVal[idxVal.length - 1] + 1).sort((x, y) => sort.order === 'desc' ?
			y[sort.key].localeCompare(x[sort.key]) : x[sort.key].localeCompare(y[sort.key]));
		data.splice(idxVal[0], idxVal.length, ...needOrderArr);

	})

}

console.log(multipleSort(sort_data, sorts));

 

posted @   JackieDYH  阅读(9)  评论(0编辑  收藏  举报  
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示