HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyMinor

Finding the indices where a selected player appears in a list of hashes

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
indicestheplayerwhereappearsselectedhashesfindinglist

Problem

I have an array of hashes in a YAML file. When I run the code below it is VERY slow. My YAML pwsarr.count is about 2000.

I am somewhat new to Ruby so I don't know if my code is not efficient or if I am doing something wrong. I know it loops my array before it's in the method and it loops in the method, but I wouldn't think it would make it as slow as it is.

def pwsplayerindex(inplayer)
    #returns array of indicies of selected player
    #if one player is in array twice you will get 2 indicies #s
    #pwsarr my array of hashes

arr = []

    pwsarr.each_with_index do |val,index|
            if val['player'] == inplayer 
                arr << index  
            end
    end
arr
end

for j in 0..pwsarr.count
    puts pwsplayerindex(pwsarr[j]['player'])
end


my array of hashes is something like this:

pwsarr =[{'player'=>'first1 last1', 'stat'=>0.0},{'player'=>'first2 last2', 'stat'=>0.0}]

Solution

Your current code is calling an \$O(n)\$ function \$n\$ times. This leads to \$O(n^2)\$ time complexity on the whole. Instead I'd make a function to change pwsarr to a Hash, where the key is the player name, and the value is a list of 'player objects'. This can then cause your program to be \$O(n)\$ as hash lookup is \$O(1)\$.

The loop can then become: (I don't know Ruby.)

pwsarr = [
    {'player'=>'first1 last1', 'stat'=>0.0},
    {'player'=>'first1 last1', 'stat'=>2.0},
    {'player'=>'first2 last2', 'stat'=>0.0}
]

def group_by(list_hash, key)
    h = Hash.new { |hash,key| hash[key] = [] }

    for hash in list_hash do
        h[hash[key]].push(hash)
    end
    h
end

pws_by_player = group_by(pwsarr, 'player')
for player in pwsarr do
    puts pws_by_player[player['player']]
end

Code Snippets

pwsarr = [
    {'player'=>'first1 last1', 'stat'=>0.0},
    {'player'=>'first1 last1', 'stat'=>2.0},
    {'player'=>'first2 last2', 'stat'=>0.0}
]

def group_by(list_hash, key)
    h = Hash.new { |hash,key| hash[key] = [] }

    for hash in list_hash do
        h[hash[key]].push(hash)
    end
    h
end

pws_by_player = group_by(pwsarr, 'player')
for player in pwsarr do
    puts pws_by_player[player['player']]
end

Context

StackExchange Code Review Q#146773, answer score: 2

Revisions (0)

No revisions yet.