2

Eg

:a=[["hello", "world"], ["good", "lord"], ["hello", "lord"]]

I need to find and record the indexes of each word with respect to the super-array. i.e

hello => 0,2
world => 0
lord => 1,2.

here's my shot ,but its very amateurish and lengthy.

all_tokens=tokens.flatten
all_tokens.each do|keyword|                                                                                      
    tokens.each do|token_array|
        if token_array.include?keyword
            x << i
        end
        i=i+1
    end    
    y[k] = x.clone
    y=y.clear
end 
2
  • Sorry.Please substitute "tokens" for "a". And "keyword" is just a looping variable. Commented Apr 8, 2010 at 2:42
  • And as flOOr mentioned, getting an array,rather a multi-dimensional array, as a result is the goal.But, once the hash is processed, and even this works ! Commented Apr 8, 2010 at 2:57

6 Answers 6

4

Slight improvement (imho) on vava's solution:

tokens = [["hello", "world"], ["good", "lord"], ["hello", "lord"]]

tokens_hash = Hash.new{|h, k| h[k] = []}

tokens.each_with_index do |subarr, i|
  subarr.each do |word|
    tokens_hash[word] << i
  end
end
Sign up to request clarification or add additional context in comments.

1 Comment

I've suggested same solution :)
2
ret = []
a.each_with_index {|x, i| if x.include?(keyword) then ret << i end }

3 Comments

I suppose keyword can be "hello", "world", "good" and "lord".
So this is an update of the part of the code from the question? Wouldn't be useful to have quoted complete working snippet here then?
generally it is not working solution. firstly keyword is not defined, secondly, even if we will define keyword ret will return array of numbers, not hash that is the goal
2
a.each_with_index.inject({}){|acc,(elem,i)|
  elem.each{|e|
    acc[e] ||= []
    acc[e] << i
  }
  acc
}
#=> {"hello"=>[0, 2], "world"=>[0], "good"=>[1], "lord"=>[1, 2]}

2 Comments

you can't use each_with_index without block
I can, in Ruby >= 1.8.7. It's returning Enumerator instance.
1
tokens = [["hello", "world"], ["good", "lord"], ["hello", "lord"]]

tokens_hash = Hash.new([])

tokens.each_with_index do |subarr, i|
    subarr.each do |word|
        tokens_hash[word] = tokens_hash[word] + [i]
    end
end

p tokens_hash #=>{"good"=>[1], "world"=>[0], "lord"=>[1, 2], "hello"=>[0, 2]}

My solution will scan the whole structure just once.

Comments

1

Just for grins, a functional solution:

#!/usr/bin/ruby1.8

a = [["hello", "world"], ["good", "lord"], ["hello", "lord"]]

b = a.flatten.uniq.inject({}) do |hash, word|
  hash.merge(word => a.each_with_index.collect do |list, i|
               list.index(word) && i
             end.compact)
end

p b    # => {"world"=>[0], "good"=>[1], "lord"=>[1, 2], "hello"=>[0, 2]}

Comments

1
a=[["hello", "world"], ["good", "lord"], ["hello", "lord"]]
result = Hash.new{|k,v| k[v] = []}
a.each_with_index{|b,i| b.each{|c| result[c] << i} }
result
#=> {"good"=>[1], "world"=>[0], "lord"=>[1, 2], "hello"=>[0, 2]}

Comments

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.