Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
  • 5 commits
  • 2 files changed
  • 0 commit comments
  • 1 contributor
Showing with 84 additions and 68 deletions.
  1. +3 −2 spec/gtl_spec.coffee
  2. +81 −66 src/gtl.coffee
View
5 spec/gtl_spec.coffee
@@ -99,9 +99,10 @@ describe 'Greater than less', ->
describe 'add custom comparator', ->
it 'should works with custom rule added to gtl.comparators', ->
- gtl.comparators.odd = (a) -> a % 2 == 1
+ gtl.comparators.add('odd', (a) -> a % 2 == 1)
+ gtl.comparators.add('even', (a) -> a % 2 != 1)
+ gtl.comparators.rehash()
gtl.filter([1, 2, 3, 4, 5], odd: true).should.eql [1, 3, 5]
- gtl.comparators.even = (a) -> a % 2 != 1
gtl.filter([1, 2, 3, 4, 5], even: true).should.eql [2, 4]
describe 'iterator rules', ->
View
147 src/gtl.coffee
@@ -38,7 +38,56 @@ Gtl = {}
# Comparator class
class Gtl.Comparator
- constructor: (names...) ->
+ filter: (array, options...) ->
+ result = []
+ for el in array
+ result.push(el) if @isElSatisfied(el, options...)
+ result
+
+ isElSatisfied: (el, rule, iterator) ->
+ satisfied = false
+
+ if iterator.constructor == Function
+ satisfied = true if @compare(iterator(el), rule)
+ else
+ satisfied = true
+
+ # Each iterator rule (or, and)
+ for iteratorRule in iterator
+
+ results = []
+
+ compare = (iterator) =>
+ results.push \
+ @compare(@getByPath(el, iterator), rule)
+
+ switch iteratorRule.iterator.constructor
+ when String
+ compare(iteratorRule.iterator)
+ when Array
+ compare(i) for i in iteratorRule.iterator
+
+ unless @isSatisfiedToIteratorRule(iteratorRule.rule, results)
+ satisfied = false
+
+ satisfied
+
+ getByPath: (obj, path) ->
+ if path.constructor == String
+ @getByPath(obj, path.split('.'))
+ else
+ if path.length == 1
+ obj[path]
+ else
+ @getByPath(obj[path[0]], path.slice(1))
+
+ isSatisfiedToIteratorRule: (rule, results) ->
+ switch rule
+ when 'or'
+ results.indexOf(true) != -1
+ when 'and'
+ results.indexOf(false) == -1
+
# Greater than comparator
class Gtl.GreaterThanComparator extends Gtl.Comparator
@@ -72,8 +121,13 @@ class Gtl.OnlyComparator extends Gtl.Comparator
# Except comparator
class Gtl.ExceptComparator extends Gtl.Comparator
names: ['not', 'except']
+
+ constructor: ->
+ @onlyComparator = new Gtl.OnlyComparator()
+
compare: (a, bs) ->
- not gtl.comparators.only(a, bs)
+ not @onlyComparator.compare(a, bs)
+
# Grep comparator
class Gtl.GrepComparator extends Gtl.Comparator
@@ -93,19 +147,33 @@ class Gtl.FuzzyComparator extends Gtl.Comparator
return false
true
+# Function comparator
+class Gtl.FunctionComparator extends Gtl.Comparator
+ constructor: (names, @compare) ->
+ super
+ @names = if names.constructor == Array
+ names
+ else
+ names.split(/,/)
+
# Comparators collection
class Gtl.ComparatorSet
constructor: ->
@comparators = []
- add: (klass) ->
- @comparators.push(new klass())
+ add: (possibleName, possibleKlass) ->
+ if possibleName.constructor == String
+ comparator = new Gtl.FunctionComparator(possibleName, possibleKlass)
+ else
+ comparator = new possibleName()
+
+ @comparators.push(comparator)
rehash: ->
for comparator in @comparators
for name in comparator.names
- @[name] = comparator.compare
+ @[name] = comparator
# Standart comparator set
class Gtl.StandartComparatorSet extends Gtl.ComparatorSet
@@ -132,77 +200,24 @@ class Gtl.Filter
constructor: ->
@comparators = new Gtl.StandartComparatorSet()
- filter: (array, rules, iterator) ->
+ filter: (array, rules, iterator = []) ->
result = clone(array)
- unless iterator
- iterator = []
+ if rules.or or rules.in
+ iterator.push(rule: 'or', iterator: rules.or || rules.in)
- if rules.or or rules.in
- iterator.push(rule: 'or', iterator: rules.or || rules.in)
+ if rules.and
+ iterator.push(rule: 'and', iterator: rules.and)
- if rules.and
- iterator.push(rule: 'and', iterator: rules.and)
-
- if iterator.length == 0
- iterator = (elm) -> elm
+ if iterator.length == 0
+ iterator = (elm) -> elm
for name, rule of rules
if ['or', 'in', 'and'].indexOf(name) == -1
- result = @filterWithComparator(result, @comparators[name], rule, iterator)
-
- result
-
- filterWithComparator: (array, comparator, rule, iterator) ->
- result = []
-
- for elm in array
- satisfied = false
-
- if iterator.constructor == Function
- satisfied = true if comparator(iterator(elm), rule)
- else
- satisfied = true
-
- # Each iterator rule (or, and)
- for iteratorRule in iterator
- do =>
-
- results = []
-
- compare = (iterator) =>
- results.push \
- comparator(@getByPath(elm, iterator), rule)
-
- switch iteratorRule.iterator.constructor
- when String
- compare(iteratorRule.iterator)
- when Array
- compare(i) for i in iteratorRule.iterator
-
- unless @isSatisfiedToIteratorRule(iteratorRule.rule, results)
- satisfied = false
-
- result.push(elm) if satisfied
+ result = @comparators[name].filter(result, rule, iterator)
result
- getByPath: (obj, path) ->
- if path.constructor == String
- @getByPath(obj, path.split('.'))
- else
- if path.length == 1
- obj[path]
- else
- @getByPath(obj[path[0]], path.slice(1))
-
- isSatisfiedToIteratorRule: (rule, results) ->
- switch rule
- when 'or'
- results.indexOf(true) != -1
- when 'and'
- results.indexOf(false) == -1
-
curry: (curriedRules, curriedIterator) ->
(array, userRules, userIterator = curriedIterator) =>
if userRules and userRules.constructor == Function

No commit comments for this range

Something went wrong with that request. Please try again.