반응형
주어진 조건과 일치하는 요소의 인덱스 찾기
배열이 주어지면 주어진 조건과 일치하는 요소의 모든 인덱스를 어떻게 찾을 수 있습니까?
예를 들어 다음과 같은 경우 :
arr = ['x', 'o', 'x', '.', '.', 'o', 'x']
항목이있는 모든 인덱스를 찾으려면 x
다음을 수행 할 수 있습니다.
arr.each_with_index.map { |a, i| a == 'x' ? i : nil }.compact # => [0, 2, 6]
또는
(0..arr.size-1).select { |i| arr[i] == 'x' } # => [0, 2, 6]
이것을 달성하는 더 좋은 방법이 있습니까?
루비 1.9 :
arr = ['x', 'o', 'x', '.', '.', 'o', 'x']
p arr.each_index.select{|i| arr[i] == 'x'} # =>[0, 2, 6]
또 다른 방법:
arr.size.times.select {|i| arr[i] == 'x'} # => [0, 2, 6]
편집하다:
이것이 필요한지 확실하지 않지만 여기에 있습니다.
벤치 마크 :
arr = 10000000.times.map{rand(1000)};
Benchmark.measure{arr.each_with_index.map { |a, i| a == 50 ? i : nil }.compact}
2.090000 0.120000 2.210000 ( 2.205431)
Benchmark.measure{(0..arr.size-1).select { |i| arr[i] == 50 }}
1.600000 0.000000 1.600000 ( 1.604543)
Benchmark.measure{arr.map.with_index {|a, i| a == 50 ? i : nil}.compact}
1.810000 0.020000 1.830000 ( 1.829151)
Benchmark.measure{arr.each_index.select{|i| arr[i] == 50}}
1.590000 0.000000 1.590000 ( 1.584074)
Benchmark.measure{arr.size.times.select {|i| arr[i] == 50}}
1.570000 0.000000 1.570000 ( 1.574474)
each_with_index.map
라인에 대한 약간의 개선
arr.map.with_index {|a, i| a == 'x' ? i : nil}.compact # => [0, 2, 6]
이 방법은 조금 더 길지만 두 배 빠릅니다.
class Array
def find_each_index find
found, index, q = -1, -1, []
while found
found = self[index+1..-1].index(find)
if found
index = index + found + 1
q << index
end
end
q
end
end
arr = ['x', 'o', 'x', '.', '.', 'o', 'x']
p arr.find_each_index 'x'
# [0, 2, 6]
AGS의 벤치 마크는이 솔루션과 함께
arr = 10000000.times.map{rand(1000)};
puts Benchmark.measure{arr.each_with_index.map { |a, i| a == 50 ? i : nil }.compact}
puts Benchmark.measure{(0..arr.size-1).select { |i| arr[i] == 50 }}
puts Benchmark.measure{arr.map.with_index {|a, i| a == 50 ? i : nil}.compact}
puts Benchmark.measure{arr.each_index.select{|i| arr[i] == 50}}
puts Benchmark.measure{arr.size.times.select {|i| arr[i] == 50}}
puts Benchmark.measure{arr.find_each_index 50}
# 1.263000 0.031000 1.294000 ( 1.267073)
# 0.843000 0.000000 0.843000 ( 0.846048)
# 0.936000 0.015000 0.951000 ( 0.962055)
# 0.842000 0.000000 0.842000 ( 0.839048)
# 0.843000 0.000000 0.843000 ( 0.843048)
# 0.405000 0.000000 0.405000 ( 0.410024)
이것이 개선이라고 생각하는지 아닌지 확실하지 않지만 ( map
+ compact
)를 필터로 사용 하면 나에게 매우 투박한 느낌이 듭니다. 그것이 목적 select
이기 때문에 나는을 사용 하고 내가 관심있는 결과의 일부를 잡습니다.
arr.each_with_index.select { |a,i| a == 'x' }.map &:last
I defined Array#index_all
which behaves like Array#index
but returns all matched indices. This method can take an argument and block.
class Array
def index_all(obj = nil)
if obj || block_given?
proc = obj ? ->(i) { self[i] == obj } : ->(i) { yield self[i] }
self.each_index.select(&proc)
else
self.each
end
end
end
require 'test/unit'
class TestArray < Test::Unit::TestCase
def test_index_all
arr = ['x', 'o', 'x', '.', '.', 'o', 'x']
result = arr.index_all('x')
assert_equal [0, 2, 6], result
arr = [100, 200, 100, 300, 100, 400]
result = arr.index_all {|n| n <= 200 }
assert_equal [0, 1, 2, 4], result
end
end
참고URL : https://stackoverflow.com/questions/13659696/find-indices-of-elements-that-match-a-given-condition
반응형
'programing' 카테고리의 다른 글
HTML 태그와 요소의 차이점은 무엇입니까? (0) | 2020.12.07 |
---|---|
목록의 Python 슬라이스 첫 번째 및 마지막 요소 (0) | 2020.12.07 |
KeyNotFoundException을 처리하는 가장 좋은 방법 (0) | 2020.12.06 |
문자열이 정수인지 확인하기위한 C # 테스트? (0) | 2020.12.06 |
C #에서 디렉터리 이름 바꾸기 (0) | 2020.12.06 |