.search(..) done -- finally figured out the propper way to cheat ;)

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2018-12-10 19:37:45 +03:00
parent 9543319a31
commit 709d50f0f6

View File

@ -311,9 +311,14 @@ var TagsPrototype = {
// //
// //
// NOTE: this is not symmetric e.g. a will match a:b but not vice-versa. // NOTE: this is not symmetric e.g. a will match a:b but not vice-versa.
match: function(a, b){ match: function(a, b, cmp){
var that = this var that = this
if(b instanceof Function){
cmp = b
b = null
}
// get matching tags... // get matching tags...
if(b == null || b instanceof Array){ if(b == null || b instanceof Array){
return (b || this.tags()) return (b || this.tags())
@ -343,14 +348,19 @@ var TagsPrototype = {
return a.length <= b.length return a.length <= b.length
&& a.filter(function(e){ && a.filter(function(e){
return e != '*' return e != '*'
&& b.indexOf(e) < 0 }).length == 0 } && b.indexOf(e) < 0
&& !(cmp
&& b.filter(cmp.bind(null, e)).length > 0) })
.length == 0 }
// path matching... // path matching...
// a matches b iff each element in a exists in b and in the same // a matches b iff each element in a exists in b and in the same
// order as in a. // order as in a.
//
// NOTE: we do not need to use cmp(..) here as we are testing
// tag compatibility deeper in matchSet(..)...
a = a.split(/[\/\\]/g) a = a.split(/[\/\\]/g)
b = b.split(/[\/\\]/g) b = b.split(/[\/\\]/g)
return b return b
.reduce(function(a, e){ .reduce(function(a, e){
return (a[0] return (a[0]
@ -358,60 +368,77 @@ var TagsPrototype = {
|| matchSet(a[0], e))) ? || matchSet(a[0], e))) ?
a.slice(1) a.slice(1)
: a : a
}, a).length == 0 }, a)
.length == 0
} }
}, },
// Search tags...
// //
// Search the tags...
// .search(str) // .search(str)
// .search(regexp)
// -> matches // -> matches
// //
// .search(str, list) // Search the given list...
// .search(regexp, list) // .search(str, tag)
// .search(str, [tag, ..])
// -> matches // -> matches
// //
// XXX should this return a list of matching tags of a list of values??? //
// ....or should we have a similar method to search values?? // This is almost the same as .match(..) but each tag is treated as
// XXX should we .match(..) the results??? // a regexp...
// ...not sure if this is needed as we are taking .tags() as input... // The rest of the tag set/path matching rules apply as-is.
// on the other hand we'd need to normalize the search string somehow... //
// ...this will likely force us into using a special regexp-like //
// search syntax with special meanings given to ':' and '/' (and '\\') // Signature differences between this and .match(..):
// XXX should we merge this with .match(..) ??? // 1) .match(..) can return a bool:
// .match(tag, tag)
// -> bool
//
// while in the same conditions .search(..) will return a list:
// .search(tag, tag)
// -> list
//
// where list is empty list if not match was found.
//
// 2) .search(..) will return individual matching tags:
// // setup a trivial example...
// var t = new Tags()
// .tag('a:b:c', 'x')
//
// // returns only the actual used tags...
// t.match('a') // -> ['a:b:c']
//
// // also returns individual tag matches...
// t.search('a') // -> ['a:b:c', 'a']
//
// NOTE: .search(..) will not build up all the possible matches
// (i.e. ['a:b:c', 'a:b', 'a:c', 'a']) and will only return
// the actual full match and an individual tag match...
// XXX should it???
search: function(query, tags){ search: function(query, tags){
var that = this var that = this
tags = tags == null ?
this.tags()
: tags instanceof Array ?
tags
: [tags]
var test = // build the search...
// predicate... var index = new Map()
query instanceof Function ? var cmp = function(a, b){
query index.has(a)
// regexp pattern... || index.set(a, new RegExp(a))
// XXX should this be here??? return index.get(a).test(b) }
: query instanceof RegExp ?
function(tag){
return query.test(tag) }
// string query...
: (function(){
query = query.split(/[\\\/]/g)
.map(function(t){
return t.includes(':') ?
t.split(/:+/g)
: t })
return function(tag){ return tags
// XXX do the test...
// XXX
} }())
return (tags || this.tags())
// split tags + include original list... // split tags + include original list...
.run(function(){ .run(function(){
return this return this
.concat(that.subTags(this)) .concat(that.subTags(this))
.unique() }) .unique() })
.filter(test.bind(this)) }, .filter(function(t){
return that.match(query, t, cmp) }) },
// Introspection... // Introspection...
// //