한 배열에 다른 배열의 모든 요소가 포함되어 있는지 확인하는 방법
주어진:
a1 = [5, 1, 6, 14, 2, 8]
다음의 모든 요소가 포함되어 있는지 확인하고 싶습니다.
a2 = [2, 6, 15]
이 경우 결과는 false
입니다.
그러한 배열 포함을 식별하는 내장 Ruby / Rails 메소드가 있습니까?
이를 구현하는 한 가지 방법은 다음과 같습니다.
a2.index{ |x| !a1.include?(x) }.nil?
더 좋고 더 읽기 쉬운 방법이 있습니까?
a = [5, 1, 6, 14, 2, 8]
b = [2, 6, 15]
a - b
=> [5, 1, 14, 8]
b - a
=> [15]
(b - a).empty?
=> false
아마도 이것은 더 읽기 쉽습니다.
a2.all? { |e| a1.include?(e) }
배열 교차를 사용할 수도 있습니다.
(a1 & a2).size == a1.size
참고 size
단지 속도 여기에 사용됩니다, 당신은 또한 (느리게) 할 수 있습니다 :
(a1 & a2) == a1
그러나 첫 번째가 더 읽기 쉽다고 생각합니다. 이 3 개는 일반 루비입니다 (레일 아님).
이것은 수행하여 달성 할 수 있습니다
(a2 & a1) == a2
이렇게하면 두 배열의 교집합이 만들어지고에있는 모든 요소가 반환 a2
됩니다 a1
. 결과가와 동일 a2
하면 모든 요소가에 포함되어 있는지 확인할 수 있습니다 a1
.
이 방법은 모든 요소 a2
가 처음에 서로 다른 경우에만 작동합니다 . 복식이 있으면이 방법은 실패합니다. Tempos의 것이 여전히 작동하므로 전적으로 그의 접근 방식을 추천합니다 (아마도 더 빠릅니다).
중복 요소가 없거나 신경 쓰지 않으면 Set 클래스를 사용할 수 있습니다 .
a1 = Set.new [5, 1, 6, 14, 2, 8]
a2 = Set.new [2, 6, 15]
a1.subset?(a2)
=> false
이 장면 뒤에서
all? { |o| set.include?(o) }
Array 클래스를 원숭이 패치 할 수 있습니다.
class Array
def contains_all?(ary)
ary.uniq.all? { |x| count(x) >= ary.count(x) }
end
end
테스트
irb(main):131:0> %w[a b c c].contains_all? %w[a b c]
=> true
irb(main):132:0> %w[a b c c].contains_all? %w[a b c c]
=> true
irb(main):133:0> %w[a b c c].contains_all? %w[a b c c c]
=> false
irb(main):134:0> %w[a b c c].contains_all? %w[a]
=> true
irb(main):135:0> %w[a b c c].contains_all? %w[x]
=> false
irb(main):136:0> %w[a b c c].contains_all? %w[]
=> true
irb(main):137:0> %w[a b c d].contains_all? %w[d c h]
=> false
irb(main):138:0> %w[a b c d].contains_all? %w[d b c]
=> true
물론이 방법은 표준 단독 방법으로 작성 될 수 있습니다.
def contains_all?(a,b)
b.uniq.all? { |x| a.count(x) >= b.count(x) }
end
그리고 당신은 그것을 호출 할 수 있습니다
contains_all?(%w[a b c c], %w[c c c])
실제로 프로파일 링 후 다음 버전이 훨씬 빠르며 코드가 더 짧습니다.
def contains_all?(a,b)
b.all? { |x| a.count(x) >= b.count(x) }
end
배열의 크기에 따라 효율적인 알고리즘 O (n log n)을 고려할 수 있습니다.
def equal_a(a1, a2)
a1sorted = a1.sort
a2sorted = a2.sort
return false if a1.length != a2.length
0.upto(a1.length - 1) do
|i| return false if a1sorted[i] != a2sorted[i]
end
end
Sorting costs O(n log n) and checking each pair costs O(n) thus this algorithm is O(n log n). The other algorithms cannot be faster (asymptotically) using unsorted arrays.
Most answers based on (a1 - a2) or (a1 & a2) would not work if there are duplicate elements in either array. I arrived here looking for a way to see if all letters of a word (split to an array) were part of a set of letters (for scrabble for example). None of these answers worked, but this one does:
def contains_all?(a1, a2)
try = a1.chars.all? do |letter|
a1.count(letter) <= a2.count(letter)
end
return try
end
'IT' 카테고리의 다른 글
iOS 2.0에서 이메일 주소를 확인하는 모범 사례는 무엇입니까 (0) | 2020.05.27 |
---|---|
Scope_Identity (), Identity (), @@ Identity 및 Ident_Current ()의 차이점은 무엇입니까? (0) | 2020.05.27 |
버튼 클릭시 양식 자동 제출 비활성화 (0) | 2020.05.27 |
null 또는 빈 문자열에 대한 변수를 확인하는 더 좋은 방법은 무엇입니까? (0) | 2020.05.27 |
“ArrayAdapter를 사용하려면 리소스 ID가 TextView 여야합니다.”xml 문제 (0) | 2020.05.27 |