2016-09-08 27 views
1

だが、私はこのようなプログラムがあるとしましょう許可:選択アレイアイテム、部分一致

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)の配列を選択私Student.keywords配列

2)と私のqueryに一致する学生は私のqueryまた、単一の単語

3)の場合の配列ですqueryが部分的にでもkeywordと一致することはstudent1するための一例のキーワードは、 "一致"

だ、次のとおりです。 ['john', 'smith', 'math', 'blue']

query配列のいずれかがMATCH

['j', 'mat'] IS、['it', 'blue', 'green']

のいずれか続くquery配列は一致しません

['johny'],['johny', 'smithy', 'mathy', 'bluegreen']

これはどのように書きますか?私は何時間も頭を掻いていて、喜びはありませんでした!

また、私は1000以上の配列要素を反復処理する必要があるので、かなりパフォーマンスが必要です。純粋なルビー溶液も必要です。

+0

'['it'、 'blue'、 'green']'は一致しません。 –

+0

コード:http://pastebin.com/5X4WwmJL。そのコアは '.grep(Regexp.new(キーワード))'部分です。配列をフィルタリングし、キーワードを含む要素だけを残します。 –

+0

もし一致する単語や部分的な単語があれば['it'、 'blue'、 'green']は一致します –

答えて

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 
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 
1

だから、基本的に限り、少なくとも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 

学生が一致していると判断しています一度ではないすべての検索用語やキーワードが検討されているので、これはかなりpreformantです。