주어진:
a1 = [5, 1, 6, 14, 2, 8]
다음의 모든 요소가 포함되어 있는지 확인하고 싶습니다.
a2 = [2, 6, 15]
이 경우 결과는 false
입니다.
그러한 배열 포함을 식별하는 내장 Ruby / Rails 메소드가 있습니까?
이를 구현하는 한 가지 방법은 다음과 같습니다.
a2.index{ |x| !a1.include?(x) }.nil?
더 좋고 더 읽기 쉬운 방법이 있습니까?
주어진:
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-a1).empty?
(a2.uniq - a1.uniq).empty?
아마도 이것은 더 읽기 쉽습니다.
a2.all? { |e| a1.include?(e) }
배열 교차를 사용할 수도 있습니다.
(a1 & a2).size == a1.size
참고 size
단지 속도 여기에 사용됩니다, 당신은 또한 (느리게) 할 수 있습니다 :
(a1 & a2) == a1
그러나 첫 번째가 더 읽기 쉽다고 생각합니다. 이 3 개는 일반 루비입니다 (레일 아님).
이것은 수행하여 달성 할 수 있습니다
(a2 & a1) == a2
그러면 두 배열의 교집합이 만들어지고 a2
in에있는 모든 요소가 반환 됩니다 a1
. 결과가와 동일 a2
하면 모든 요소가에 포함되어 있는지 확인할 수 있습니다 a1
.
이 방법은 모든 요소 a2
가 처음에 서로 다른 경우에만 작동합니다 . 복식이 있으면이 방법은 실패합니다. Tempos의 것이 여전히 작동하므로 전적으로 그의 접근 방식을 추천합니다 (아마도 더 빠릅니다).
length
방법은 훨씬 더 수행합니다
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
정렬 비용 O (n log n) 및 각 쌍을 확인하는 데 비용 O (n)이 있으므로이 알고리즘은 O (n log n)입니다. 정렬되지 않은 배열을 사용하면 다른 알고리즘이 더 빠를 수 없습니다.