2016-09-12 7 views
4

주문이 중요한 두 배열 간의 차이점을 계산하려고합니다. 예를 들어이 3 개 차이를 얻을 것이다루비 : 2 배열, 주문 문제의 차이점을 찾는 방법

array_one = ["A", "B", "C"] 
array_two = ["B", "C", "A"] 

이유는

array_one[0] != array_two[0] 
array_one[1] != array_two[1] 
array_one[2] != array_two[2] 

또 다른 예 : 크게

array_one[0] == array_two[0] 
array_one[1] != array_two[1] 
array_one[2] == array_two[2] 

어떤 제안이 1 인해를 얻을 것이다

array_one = ["Z", "X", "Y"] 
array_two = ["Z", "W", "Y"] 

고맙습니다.

답변

5

방법이

array_one = ["A", "B", "C"] 
array_two = ["A", "C", "A"] 

array_one.select.each_with_index { |item, index| 
    array_two[index] != item 
} => #B and C 
+0

최근에 .select를 사용하는 많은 메소드를 보아 왔습니다. 어떻게 이러한 조합을 찾으십니까? 문서는'.select.each_with_index'를 플러그인 할 때 일어나는 일을 실제로 보여주지 않습니다. –

+0

완벽! 감사. – morrime

+0

@KaMok, 예, 문서에는 특정 기능 또는 메소드와 관련된 부분 만 표시됩니다. 예를 들어,이 경우 [ruby array select] (https://ruby-doc.org/core-2.2.0/Array.html#method-i-select) 문서가 표시되면 select가 '열거 자 '. 및 [Enumerator docs] (http://ruby-doc.org/core-2.0.0/Enumerator.html)에는 이들과 함께 사용할 수있는 방법이 나와 있습니다. 처음에는 조금 힘들었지 만, 시간이 흐르면서 방법이 다른 방법으로 연결될 수있는 방법을 알게되었습니다. 문서를 읽으면이 문제를 개선하는 데 도움이됩니다 .. – sameera207

4

zip을 사용하여 두 배열을 병합하고 두 값이 같은 내부 배열을 계산할 수 있습니다.

arr1 = [1,2,3] 
arr2 = [1,5,6] 

arr1.zip(arr2)    #=> [[1, 1], [2, 5], [3, 6]] 
    .count {|a, b| a == b} #=> 1 

또 다른 방법은 그냥 카운터 물론

count = 0 

(0...arr1.length).each do |idx| 
    count += 1 if arr1[idx] == arr2[idx] 
end 

, 모두 두 배열은 같은 길이 있다고 가정에게 모두 배열을 반복 실행합니다.

(0...arr1.length)0 to arr1.length-1과 동일하고 ...은 독점입니다. davidhu2000 @

+0

(난 그냥 더 의미있는 결과를 얻기 위해 더 큰 하나의 배열을 전환) : //apidock.com/ruby/Enumerator/each_with_index – Ninigi

+0

블록 안에 'arr1_val == arr2 [idx]'같은 것을 갖기 때문에이 경우 each_with_index의 팬이 아닙니다. 나는 그것을 균등성을 위해서 내 방식대로했습니다. – davidhu2000

1

그것에 나를 이길하지만이 방법으로 는 아직 언급 할 가치가있을 수도, 약간 다릅니다 :

array_one = ["A", "B", "C"] 
array_two = ["B", "C", "A"] 

array_one.zip(array_two).inject(0) { |memo, (left, right)| 
    unless left == right 
    memo + 1 
    else 
    memo 
    end 
} # => 3 
1

방법

이 약에 대해
array_one = ["A", "B", "C"] 
array_two = ["A", "C", "A"] 

array_one.select.each_with_index { |item, index| 
    array_two[index] != item 
} => #["B", "C"] 
2

내가 이런 물건을 좋아하기 때문에, 나는 단지 누군가가 관심이 경우 공유하기를 원해요, 솔루션을 벤치마킹하면 #each_with_index에 http를 사용할 수있는 루비 버전에 따라

require "benchmark/ips" 

def method_1(ar_1, ar_2) 
    ar = ar_1.zip ar_2 

    ar.count { |els| els[0] == els[1] } 
end 

def method_2(ar_1, ar_2) 
    count = 0 
    ar_1.each_with_index { |el, i| count += 1 if el == ar_2[i] } 
end 

def method_3(ar_1, ar_2) 
    count = 0 

    (0...ar_1.length).each do |idx| 
    count += 1 if ar_1[idx] == ar_2[idx] 
    end 
end 

def method_4(ar_1, ar_2) 
    ar_1.zip(ar_2).inject(0) do |memo, (left, right)| 
    if left == right 
     memo 
    else 
     memo + 1 
    end 
    end 
end 

def method_5(ar_1, ar_2) 
    ar_1.select.each_with_index do |item, index| 
    ar_2[index] != item 
    end 
end 

Benchmark.ips do |x| 
    # ar_1 = ["A", "B", "C"] 
    # ar_2 = ["B", "C", "A"] 

    ar_1 = (0..1_000_000).to_a.shuffle 
    ar_2 = (0..1_000_000).to_a.shuffle 

    x.report("zip and count") do |times| 
    i = 0 
    while i < times 
     method_1 ar_1, ar_2 
     i += 1 
    end 
    end 

    x.report("each with index") do |times| 
    i = 0 
    while i < times 
     method_2 ar_1, ar_2 
     i += 1 
    end 
    end 

    x.report("0..length each") do |times| 
    i = 0 
    while i < times 
     method_3 ar_1, ar_2 
     i += 1 
    end 
    end 

    x.report("zip and inject") do |times| 
    i = 0 
    while i < times 
     method_4 ar_1, ar_2 
     i += 1 
    end 
    end 

    x.report("select each with index") do |times| 
    i = 0 
    while i < times 
     method_5 ar_1, ar_2 
     i += 1 
    end 
    end 

    x.compare! 
end 

################################################### 
# 10_000 elements per array      # 
################################################### 
# 
# Warming up -------------------------------------- 
#  zip and count 54.000 i/100ms 
#  each with index 92.000 i/100ms 
#  0..length each 87.000 i/100ms 
#  zip and inject 41.000 i/100ms 
# select each with index 
#       82.000 i/100ms 
# Calculating ------------------------------------- 
#  zip and count 545.700 (± 2.6%) i/s -  2.754k in 5.050362s 
#  each with index 919.259 (± 3.0%) i/s -  4.600k in 5.008972s 
#  0..length each 919.908 (± 1.4%) i/s -  4.611k in 5.013518s 
#  zip and inject 413.470 (± 1.7%) i/s -  2.091k in 5.058865s 
# select each with index 
#       828.774 (± 3.5%) i/s -  4.182k in 5.053036s 
# 
# Comparison: 
#  0..length each:  919.9 i/s 
#  each with index:  919.3 i/s - same-ish: difference falls within error 
# select each with index:  828.8 i/s - 1.11x slower 
#  zip and count:  545.7 i/s - 1.69x slower 
#  zip and inject:  413.5 i/s - 2.22x slower 


################################################### 
# 1_000_000 elements per array      # 
################################################### 
# 
# Warming up -------------------------------------- 
#  zip and count  1.000 i/100ms 
#  each with index  1.000 i/100ms 
#  0..length each  1.000 i/100ms 
#  zip and inject  1.000 i/100ms 
# select each with index 
#       1.000 i/100ms 
# Calculating ------------------------------------- 
#  zip and count  5.447 (±18.4%) i/s -  26.000 in 5.088342s 
#  each with index  9.292 (± 0.0%) i/s -  47.000 in 5.058805s 
#  0..length each  9.104 (± 0.0%) i/s -  46.000 in 5.053701s 
#  zip and inject  3.983 (± 0.0%) i/s -  20.000 in 5.042810s 
# select each with index 
#       7.777 (±12.9%) i/s -  39.000 in 5.053795s 
# 
# Comparison: 
#  each with index:  9.3 i/s 
#  0..length each:  9.1 i/s - 1.02x slower 
# select each with index:  7.8 i/s - 1.19x slower 
#  zip and count:  5.4 i/s - 1.71x slower 
#  zip and inject:  4.0 i/s - 2.33x slower 
1
array_one = ["A", "B", "C"] 
array_two = ["A", "C", "A"] 

enum_two = array_two.to_enum 
array_one.select { |s| s != enum_two.next } 
    #=> ["B", "C"]