added natural sort...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-11-25 17:39:18 +03:00
parent 41fbe200f3
commit 145f6d7982
2 changed files with 57 additions and 14 deletions

View File

@ -712,7 +712,11 @@ module.BaseStore = {
// //
// NOTE: all path based <by> values are sync, not requireing a .gat(..) // NOTE: all path based <by> values are sync, not requireing a .gat(..)
// and thus faster than sorting via arbitrary <attr>... // and thus faster than sorting via arbitrary <attr>...
// NOTE: this performs a natural sort, i.e. numbers in strings are
// treated as numbers and not as strings of characters making
// "page2" precede "page10".
// //
// XXX should this be an index/cached??
__sort_method__: { __sort_method__: {
// NOTE: path/location are special cases as they do not transform // NOTE: path/location are special cases as they do not transform
// the path -- they are hard-coded in .sort(..)... // the path -- they are hard-coded in .sort(..)...
@ -739,9 +743,36 @@ module.BaseStore = {
|| paths.includes('**')) ? || paths.includes('**')) ?
this.match(paths).iter() this.match(paths).iter()
: paths : paths
// natural compare arrays...
var nsplit = function(e){
return typeof(e) == 'string' ?
e.split(/(\d+)/g)
.map(function(e){
var i = parseInt(e)
return isNaN(i) ?
e
: i })
: e }
var ncmp = function(a, b){
// skip the equal part...
var i = 0
while(a[i] != null
&& b[i] != null
&& a[i] == b[i]){
i++ }
return (a[i] == null
&& b[i] == null) ?
0
: (a[i] == null
|| a[i] < b[i]) ?
-1
: (b[i] == null
|| a[i] > b[i]) ?
1
: 0 }
var _async = false var _async = false
return paths return paths
// pre-fetch all the needed data... // pre-fetch and prep all the needed data...
// XXX we can try and make this lazy and only get the data // XXX we can try and make this lazy and only get the data
// we need when we need it (in sort)... // we need when we need it (in sort)...
// ...not sure if this is worth it... // ...not sure if this is worth it...
@ -763,18 +794,19 @@ module.BaseStore = {
cmp.slice(1) cmp.slice(1)
: cmp : cmp
res.push( res.push(
(cmp == 'path' nsplit(
|| cmp == 'location') ? (cmp == 'path'
p || cmp == 'location') ?
: cmp in that.__sort_method__ ? p
that.__sort_method__[cmp].call(that, p) : cmp in that.__sort_method__ ?
// async attr... that.__sort_method__[cmp].call(that, p)
: typeof(cmp) == 'string' ? // async attr...
// NOTE: we only get page data once per page... : typeof(cmp) == 'string' ?
(d = d ?? that.get(p)) // NOTE: we only get page data once per page...
.then(function(data){ (d = d ?? that.get(p))
return data[cmp] }) .then(function(data){
: null) } return data[cmp] })
: null)) }
_async = _async || !!d _async = _async || !!d
return d ? return d ?
// wait for data to resolve... // wait for data to resolve...
@ -793,6 +825,15 @@ module.BaseStore = {
((ca[i] == null ((ca[i] == null
&& cb[i] == null) ? && cb[i] == null) ?
0 0
// natural cmp...
: (ca[i] instanceof Array
&& cb[i] instanceof Array) ?
ncmp(ca[i], cb[i])
: ca[i] instanceof Array ?
ncmp(ca[i], [cb[i]])
: cb[i] instanceof Array ?
ncmp([ca[i]], cb[i])
// normal indexed cmp...
: (cb[i] == null : (cb[i] == null
|| ca[i] < cb[i]) ? || ca[i] < cb[i]) ?
-1 -1

View File

@ -37,7 +37,7 @@
* - * -
* *
* *
* XXX revise how we store order... * XXX sort: revise how we store order...
* .metadata.order = [ .. ] * .metadata.order = [ .. ]
* .metadata.order_<name> = [ .. ] * .metadata.order_<name> = [ .. ]
* ... * ...
@ -47,6 +47,8 @@
* <name>: [ .. ] * <name>: [ .. ]
* ... * ...
* } * }
* ...this would make updating order more complicated (i.e. require a fetch)
* Q: will it be a good idea to use the cache/index api???
* XXX macros: else/default macro args essentially mean the same thing, should we * XXX macros: else/default macro args essentially mean the same thing, should we
* unify them to use the same name??? * unify them to use the same name???
* XXX parser: error handling: revise page quoting... * XXX parser: error handling: revise page quoting...