多列排序/多条件排序的深入探讨

By admin at 2022-01-29 • 0人收藏 • 593人看过

所谓多列排序, 即多条件排序, 是有先后顺序分主次的排序要求.

首先满足A条件, 然后再满足B条件.......



更新:

新版aardio增加了

import web.script.json

可以取代楼下的加载json解析代码

//加载JSON转换库
var loadJSON2 = string.load("\json2.js");

只要使用了web.script.json就可以不用load了.

下面的代码内部就可以直接使用

JSON.stringify
JSON.parse

了.

7 个回复 | 最后更新于 2022-02-12
2022-01-30   #1

多列排序 / 多条件排序


利用多列条件排序的js库 thenby.js 

https://github.com/Teun/thenBy.js

/***    
   Copyright 2013 Teun Duynstee    
   Licensed under the Apache License, Version 2.0 (the "License");    
   you may not use this file except in compliance with the License.    
   You may obtain a copy of the License at    
     http://www.apache.org/licenses/LICENSE-2.0    
   Unless required by applicable law or agreed to in writing, software    
   distributed under the License is distributed on an "AS IS" BASIS,    
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.    
   See the License for the specific language governing permissions and    
   limitations under the License.    
*/    
var firstBy = (function() {    
function identity(v){return v;}    
function ignoreCase(v){return typeof(v)==="string" ? v.toLowerCase() : v;}    
function makeCompareFunction(f, opt){    
opt = typeof(opt)==="object" ? opt : {direction:opt};    
if(typeof(f)!="function"){    
var prop = f;    
// make unary function    
f = function(v1){return !!v1[prop] ? v1[prop] : "";}    
}    
if(f.length === 1) {    
// f is a unary function mapping a single item to its sort score    
var uf = f;    
var preprocess = opt.ignoreCase?ignoreCase:identity;    
var cmp = opt.cmp || function(v1,v2) {return v1 < v2 ? -1 : v1 > v2 ? 1 : 0;}    
f = function(v1,v2) {return cmp(preprocess(uf(v1)), preprocess(uf(v2)));}    
}    
const descTokens = {"-1":'', desc:''};    
if(opt.direction in descTokens) return function(v1,v2){return -f(v1,v2)};    
return f;    
}    
/* adds a secondary compare function to the target function (`this` context)    
       which is applied in case the first one returns 0 (equal)    
       returns a new compare function, which has a `thenBy` method as well */    
function tb(func, opt) {    
/* should get value false for the first call. This can be done by calling the     
        exported function, or the firstBy property on it (for es6 module compatibility)    
        */    
var x = (typeof(this) == "function" && !this.firstBy) ? this : false;    
var y = makeCompareFunction(func, opt);    
var f = x ? function(a, b) {    
return x(a,b) || y(a,b);    
}    
: y;    
f.thenBy = tb;    
return f;    
}    
tb.firstBy = tb;    
return tb;    
})();


aardio调用thenby.js示例下载:

thenBy排序的简单调用.zip


aardio调用thenby.js示例:

测试中发现, 如果直接在js代码中用JSON.Stringfy( )会提示null错误, 所以需要手动引用json解析库.

import console; 

import web.script;
var vm = web.script();
//加载JSON转换库
var loadJSON2 = string.load("\json2.js");
//加载thenBy排序库
var loadThenBy = string.load("\thenBy.min.js");
//编写用户函数
var mainJS = /*  
      function output(sdata) {
         var data = JSON.parse(sdata);
         s = firstBy(function (v1, v2) { return v1.name.length - v2.name.length; })
                 .thenBy(function (v1, v2) { return v1.population - v2.population; })
                 .thenBy(function (v1, v2) { return v1.id - v2.id; });
        data.sort(s);
        return JSON.stringify(data);
      }  
*/
vm.AddCode( loadJSON2++loadThenBy++mainJS ); //加载脚本

var tab = {
        	{ id: 7, name:  "Amsterdam", population: 750000, country: "Netherlands" },
            { id: 12, name: "The Hague", population: 450000, country: "Netherlands" },
            { id: 43, name: "Rotterdam", population: 600000, country: "Netherlands" },
            { id: 5, name:  "Berlin", population: 3000000, country: "Germany" },
            { id: 42, name: "Dsseldorf", population: 550000, country: "Germany" },
            { id: 44, name: "Stuttgard", population: 600000, country: "Germany" },
        }

console.dump( web.json.tryParse(vm.Run("output",web.json.stringify(tab))) )

console.pause(true);

image.png

2022-01-30   #2

回到 两列排序 


这时候用thenby.js应该怎么写?

import console; 

import web.script;
var vm = web.script();
//加载JSON转换库
var loadJSON2 = string.load("\json2.js");
//加载thenBy排序库
var loadThenBy = string.load("\thenBy.min.js");
//编写用户函数
var mainJS = /*  
      function output(sdata) {
         var data = JSON.parse(sdata);
         s = firstBy(function (v1, v2) { return v1[0] - v2[0]; })
                 .thenBy(function (v1, v2) { return v1[1] - v2[1]; })
        data.sort(s);
        return JSON.stringify(data);
      }  
*/
vm.AddCode( loadJSON2++loadThenBy++mainJS ); //加载脚本

var tab = {
        	{50,80};
    		{20,24};
    		{1,3};
    		{4,9};
    		{100,103};
    		{4,8};
        }

console.dump( web.json.tryParse(vm.Run("output",web.json.stringify(tab))) )

console.pause(true);

image.png

2022-01-30   #3

更多列排序测试

import console; 

import web.script;
var vm = web.script();
//加载JSON转换库
var loadJSON2 = string.load("\json2.js");
//加载thenBy排序库
var loadThenBy = string.load("\thenBy.min.js");
//编写用户函数
var mainJS = /*  
      function output(sdata) {
         var data = JSON.parse(sdata);
         s = firstBy(function (v1, v2) { return v1[0] - v2[0]; })
                 .thenBy(function (v1, v2) { return v1[1] - v2[1]; })
                 .thenBy(function (v1, v2) { return v1[2] - v2[2]; })
        data.sort(s);
        return JSON.stringify(data);
      }  
*/
vm.AddCode( loadJSON2++loadThenBy++mainJS ); //加载脚本

var tab = {
        	{50,80,32,7633};
    		{20,24,543,45};
    		{1,3,897,453};
    		{4,3,78,35};
    		{100,33,453,3341};
    		{4,3,8,38};
        }

console.dump( web.json.tryParse(vm.Run("output",web.json.stringify(tab))) )

console.pause(true);

image.png

结果也是正确的.

2022-01-30   #4

排序颠倒 , 或者按照升降序排列 的设置

thenBy.js提供了一些常用配置, 具体可以百度搜下, 最简单的是排序方程后面加-1来颠倒顺序

import console; 

import web.script;
var vm = web.script();
//加载JSON转换库
var loadJSON2 = string.load("\json2.js");
//加载thenBy排序库
var loadThenBy = string.load("\thenBy.min.js");
//编写用户函数
var mainJS = /*  
      function output(sdata) {
         var data = JSON.parse(sdata);
         s = firstBy(function (v1, v2) { return v1[0] - v2[0]; },-1)
                 .thenBy(function (v1, v2) { return v1[1] - v2[1]; },-1)
        data.sort(s);
        return JSON.stringify(data);
      }  
*/
vm.AddCode( loadJSON2++loadThenBy++mainJS ); //加载脚本

var tab = {
        	{-50,-80,32,7633};
    		{-20,-24,543,45};
    		{-1,-3,897,453};
    		{-4,-3,78,35};
    		{-100,-33,453,3341};
    		{-4,-2.3,8,38};
        }

console.dump( web.json.tryParse(vm.Run("output",web.json.stringify(tab))) )

console.pause(true);

image.png


2022-02-02   #5

还是aardio简洁!

2022-02-12   #6
# Python改写
tab = [
        { 'id': 7, 'name':  "Amsterdam", 'population': 750000, 'country': "Netherlands" },
        { 'id': 12, 'name': "The Hague", 'population': 450000, 'country': "Netherlands" },
        { 'id': 43, 'name': "Rotterdam", 'population': 600000, 'country': "Netherlands" },
        { 'id': 5, 'name':  "Berlin", 'population': 3000000, 'country': "Germany" },
        { 'id': 42, 'name': "Dsseldorf", 'population': 550000, 'country': "Germany" },
        { 'id': 44, 'name': "Stuttgard", 'population': 600000, 'country': "Germany" },
]

tab.sort(key=lambda x: (len(x['name']), x['population'], x['id']))

输出

C:\Users\Administrator\anaconda3\python.exe C:/Users/Administrator/Documents/PythonProject/spreadsheetlight/sort_test.py
{'id': 5, 'name': 'Berlin', 'population': 3000000, 'country': 'Germany'}
{'id': 12, 'name': 'The Hague', 'population': 450000, 'country': 'Netherlands'}
{'id': 42, 'name': 'Dsseldorf', 'population': 550000, 'country': 'Germany'}
{'id': 43, 'name': 'Rotterdam', 'population': 600000, 'country': 'Netherlands'}
{'id': 44, 'name': 'Stuttgard', 'population': 600000, 'country': 'Germany'}
{'id': 7, 'name': 'Amsterdam', 'population': 750000, 'country': 'Netherlands'}


Python对于这种排序什么的是非常方便的,aardio中使用python又是非常方便的,python中排好序,aardio直接调用就好了,哈哈

2022-02-12   #7

回复#8 @jacen :

其实你的aardio里面的py3扩展库调用python代码很方便的,封装以后体积也不大,至少比python打包成exe以后的体积小得多。

登录后方可回帖

登 录
信息栏
公告:
个人博客
专注分享
谢谢合作!

本站域名:HtmLayout.Cn
aardio可以快速开发上位机,本站主要记录了学习过程中遇到的问题和解决办法及aardio代码分享

这里主要专注于aardio学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.

Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
本 站 主 站:Stm32cube中文网
Sciter中文在线文档Sciter在线学习文档
空间赞助:才仁机械
打赏本站
Loading...