假设我有一个这样的程序:
class Student
attr_reader :first_name, :last_name, :subject, :color
def initialize(first_name, last_name, subject, color)
@first_name = first_name
@last_name = last_name
@subject = subject
@color = color
end
def keywords
[] << @first_name << @last_name << @subject << @color
end
end
student1 = Student.new('john', 'smith', 'math', 'blue')
student2 = Student.new('ann', 'smitten', 'english', 'blue')
students = [student1, student2]
students.select do |student|
...
end
我正在努力完成以下任务:
1)选择与我的query
匹配的学生数组与我的Student.keywords数组
2)我的query
也是一个单词数组
3)如果query
甚至部分匹配keyword
,那么它就是“匹配”
例如student1
的关键字是:
['john', 'smith', 'math', 'blue']
以下任何query
数组是一个匹配
['j', 'mat']
,['it', 'blue', 'green']
以下任何query
数组都不是匹配
['johny']
,['johny', 'smithy', 'mathy', 'bluegreen']
我怎么写这个?我一直在挠头几个小时,没有快乐!
另外,我确实需要这个是相当高效的,因为我可能需要迭代超过1000个或更多的数组元素。我也需要纯红宝石溶液。
答案 0 :(得分:1)
所以基本上只要至少有一个元素匹配,它就匹配了吗?
def match(search_array, student_array)
# initialize output array
matching_students = []
# iterate through all students
student_array.each do |student|
# this student not yet matching
matched_student = false
# iterate through student's keywords
student.keywords.each do |keyword|
# iterate through search words
search_array.each do |word|
# test for match
if keyword.start_with? word
# add to array
matching_students << student
# flag current student as matched
matched_student = true
end
# don't continue with search array if student already matched
break if matched_student
end
# don't continue with student.keywords if student already matched
break if matched_student
end
end
matching_students
end
这是相当有说服力的,因为并非所有搜索字词和关键字在确定学生匹配后都会被检查。
答案 1 :(得分:1)
这是工作代码。纯红宝石和所有。它的核心是.grep(Regexp.new(keyword))
部分。它过滤数组,只留下那些包含关键字的元素。
class Student
attr_reader :first_name, :last_name, :subject, :color
def initialize(first_name, last_name, subject, color)
@first_name = first_name
@last_name = last_name
@subject = subject
@color = color
end
def keywords
[ first_name, last_name, subject, color ]
end
end
class Matcher
attr_reader :student, :search_keywords
def initialize(student, search_keywords)
@student = student
@search_keywords = search_keywords
end
def match?
search_keywords.any? do |kw|
student.keywords.grep(Regexp.new(kw)).length > 0
end
end
end
def count_results(students, query)
students.select {|s| Matcher.new(s, query).match? }.length
end
student1 = Student.new('john', 'smith', 'math', 'blue')
student2 = Student.new('ann', 'smitten', 'english', 'blue')
students = [student1, student2]
count_results(students, ['j', 'mat']) # => 1
count_results(students, ['it', 'blue', 'green']) # => 2
count_results(students, ['johny']) # => 0
count_results(students, ['johny', 'smithy', 'mathy', 'bluegreen']) # => 0
答案 2 :(得分:0)
不是最有效率,而是直截了当地做你想做的事情:
class Student
attr_reader :first_name, :last_name, :subject, :color
def initialize(first_name, last_name, subject, color)
@first_name = first_name
@last_name = last_name
@subject = subject
@color = color
end
def keywords
[first_name, last_name, subject, color]
end
def matches_search?(search_terms)
search_terms.any? { |search_term| keywords.find { |kw| kw.match(search_term) } }
end
end
student1 = Student.new('john', 'smith', 'math', 'blue')
student2 = Student.new('ann', 'smitten', 'english', 'blue')
students = [student1, student2]
should_match = [['j', 'mat'], ['it', 'blue', 'green']]
should_not_match = ['johny'], ['johny', 'smithy', 'mathy', 'bluegreen']
should_match.map { |search| students.select { |student| student.matches_search?(search) } }
# returns an array of 2 times student one
should_not_match.map { |search| students.select { |student| student.matches_search?(search) } }
# two empty arrays, i.e. no student matched