鉴于我有一个巨大的数组,以及它的值。我想获得数组中的值的索引。有没有其他的方法,而不是打电话Array#index
得到它?这个问题来自保持真正巨大的阵列的需要并且呼叫Array#index
巨大的时间。获取数组元素的索引比O(n)更快
多试几次后,我发现,缓存中的元素指标通过存储结构与(value, index)
领域,而不是本身的价值给出了性能的一大步(20X次夺冠)。
我还想知道是否有一种更方便的方式来查找没有缓存的en元素索引(或者有一个好的缓存技术可以提高性能)。
鉴于我有一个巨大的数组,以及它的值。我想获得数组中的值的索引。有没有其他的方法,而不是打电话Array#index
得到它?这个问题来自保持真正巨大的阵列的需要并且呼叫Array#index
巨大的时间。获取数组元素的索引比O(n)更快
多试几次后,我发现,缓存中的元素指标通过存储结构与(value, index)
领域,而不是本身的价值给出了性能的一大步(20X次夺冠)。
我还想知道是否有一种更方便的方式来查找没有缓存的en元素索引(或者有一个好的缓存技术可以提高性能)。
将数组转换为散列。然后寻找钥匙。
array = ['a', 'b', 'c']
hash = Hash[array.map.with_index.to_a] # => {"a"=>0, "b"=>1, "c"=>2}
hash['b'] # => 1
有没有好的理由不使用哈希?查找数组为O(1)
与O(n)
。
重点是 - 我打电话'#keys'哈希,它返回我使用数组。不过,我可能会考虑我的架构以及... – gmile 2011-06-05 12:29:28
如果它是一个分类阵列可以使用二进制搜索算法(O(log n)
)。例如,使用此功能扩展Array类:
class Array
def b_search(e, l = 0, u = length - 1)
return if lower_index > upper_index
midpoint_index = (lower_index + upper_index)/2
return midpoint_index if self[midpoint_index] == value
if value < self[midpoint_index]
b_search(value, lower_index, upper_index - 1)
else
b_search(value, lower_index + 1, upper_index)
end
end
end
为什么不使用索引或rindex?
array = %w(a b c d e)
# get FIRST index of element searched
puts array.index('a')
# get LAST index of element searched
puts array.rindex('a')
指数:http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-index
RINDEX:http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-rindex
以@泽的回答的组合和那里列出的评论,你可以实现阵列上的 “快速” 指数和RINDEX类。
class Array
def quick_index el
hash = Hash[self.map.with_index.to_a]
hash[el]
end
def quick_rindex el
hash = Hash[self.reverse.map.with_index.to_a]
array.length - 1 - hash[el]
end
end
其他答案没有考虑到一个条目在列表中多次列出的可能性。这将返回一个散列结果,其中每个键是数组中唯一的对象和每个值是索引数组对应于对象的居住地:
a = [1, 2, 3, 1, 2, 3, 4]
=> [1, 2, 3, 1, 2, 3, 4]
indices = a.each_with_index.inject(Hash.new { Array.new }) do |hash, (obj, i)|
hash[obj] += [i]
hash
end
=> { 1 => [0, 3], 2 => [1, 4], 3 => [2, 5], 4 => [6] }
这样就可以快速搜索重复的条目:
indices.select { |k, v| v.size > 1 }
=> { 1 => [0, 3], 2 => [1, 4], 3 => [2, 5] }
如果您的数组有自然顺序使用二进制搜索。
使用二进制搜索。
二进制搜索有O(log n)
访问时间。
下面是关于如何使用二进制搜索的步骤,
bsearch
找到的元素或指数代码示例
# assume array is sorted by name!
array.bsearch { |each| "Jamie" <=> each.name } # returns element
(0..array.size).bsearch { |n| "Jamie" <=> array[n].name } # returns index
如果阵列很长,则速度最快 – Kevin 2012-11-19 19:13:50
根据您的使用情况,如果存在重复值,则可能会出现问题。 上述方法将返回等价或#rindex(最后一次出现的值) 要获得#index等效结果,意味着返回值的第一个索引的散列需要沿着反转的方向在创建散列之前的数组,然后从初始数组的总长度中减去返回的索引值 - 1. #(array.length - 1) - hash ['b'] – ashoda 2013-05-30 02:49:37
不转换为散列准时?我猜想如果它将被多次使用,那么散列转换将更加高效。但对于一次性使用,是否没有不同,然后遍历数组? – ahnbizcad 2016-09-16 19:45:53