1

Let say I have an array

[1, 2, 3, 4, 3, 2]

I wonder how I can get the hash { 1 => 0, 4 => 3 } (value => index). I need the index of the earlier occurrence.

1
  • 2
    What do you mean "I need index of earlier occurence"? if you need only UNIQUE elements, they they only occur once. Commented Sep 9, 2015 at 14:49

2 Answers 2

2

Could also try this

unique = array.select { |a| array.count(a) === 1 }
indexes = unique.map { |u| array.index(u) }
Hash[unique.zip(indexes)]

My algorithm is to first generate a new array of the single elements. I do that by filtering the array for the one's where the count is equal to 1. We can use the array#count method.

I then create a second array, where I map the values of the first array, to their indexes in the original array.

I then combine the values using the array#zip function and convert to a hash with Hash.

Output

{ 1 => 0, 4 => 3 }
Sign up to request clarification or add additional context in comments.

3 Comments

This is very expensive, complexity of O(n^2)
Understood, that's why I edited the post. Thanks for pointing this out
As a note you could cut this down one line by using Hash[unique.map{ |u| [u,array.index(u)]}] rather than map and then zip just zip them in the mapping. OR even a 1 liner would be Hash[array.select{|a| array.count(a) == 1 }.map{ |u| [u,array.index(u)]}]
2
a.each_with_index.with_object({}) { |(e, i), h| h.key?(e) ? h[e] = nil : h[e] = i }
 .reject! { |k, v| v.nil? }

5 Comments

For readability, perhaps you should use some other value (like nil) instead of -1.
You can also use .each_with_index.with_object({}){|(e, i), h| to make it look better.
rather than overwriting duplicate values then rejecting them why not avoid inserting them at all e.g. a.each_with_index.with_object({}) { |(e, i), h| h[e] = i if a.count(e) == 1 }
you can put the assign first, i.e. h[e] = h.has_key?(e) ? nil : i and instead of rejecting nil values, you could select non-nil values using select { |k, v| v }
note that reject! returns nil if nothing was rejected, you have to use the non-bang methods (either reject or select)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.