Николай обнови решението на 06.11.2013 02:44 (преди около 11 години)
+class Criteria
+ class << self
+ def status(checkFor)
+ Criteria.new(-> (tested) { tested.status == checkFor })
+ end
+
+ def priority(priorityToCheck)
+ Criteria.new(-> (tested) { tested.priority == priorityToCheck })
+ end
+
+ def tags(tagsNeeded)
+ Criteria.new(-> (tested) { (tagsNeeded - tested.tags).empty? })
+ end
+ end
+
+ def &(against)
+ Criteria.new(->(x) { @lambdaTest.call(x) & against.lambdaTest.call(x) })
+ end
+
+ def |(against)
+ Criteria.new(->(x) { @lambdaTest.call(x) | against.lambdaTest.call(x) })
+ end
+
+ def !
+ Criteria.new(->(x) { not @lambdaTest.call(x) } )
+ end
+
+ def initialize(lambdaTest)
+ @lambdaTest = lambdaTest
+ end
+
+ attr_accessor :lambdaTest
+end
+
+class Task
+ attr_accessor :status
+ attr_accessor :description
+ attr_accessor :priority
+ attr_accessor :tags
+
+ def initialize(args)
+ statusString, @description, priorityString, tagsString = refine(args,'|')
+ @status = statusString.downcase.to_sym
+ @priority = priorityString.downcase.to_sym
+ @tags = tagsString ? refine(tagsString,',') : []
+ end
+
+ private def refine(args,separator)
+ args.split(separator).map { |item| item.strip }
+ end
+end
+
+class TodoList < Array
+ def tasks_todo
+ count { |task| task.status == :todo }
+ end
+
+ def tasks_in_progress
+ count { |task| task.status == :current }
+ end
+
+ def tasks_completed
+ count { |task| task.status == :done }
+ end
+
+ def completed?
+ all? { |task| task.status == :done }
+ end
+
+ def filter(criterion)
+ filtered =TodoList.new
+ each { |item| filtered << item }
+ filtered.select! { |item| criterion.lambdaTest.call(item) }
+ end
+
+ def TodoList.parse(text)
+ emptyList = Array::TodoList.new
+ text.lines.reduce(emptyList) { |tasks,line| tasks << Task.new(line) }
+ end
+
+ alias adjoin +
+end
+