flipn
flipn

Reputation: 23

Get single hash from array

I have an array of hashes:

[<name: bob, age: 25, orders: 3>, <name: george, age: 21, orders: 2>, <name: sandy, age: 23, orders: 5>, <name: sandy, age: 21, orders: 4>]

I'd like a function that picks out a single hash based on two entries. Ie I put in name="sandy" age=21. It would come back with a simple hash <name: sandy, age:21, orders: 4>

I tried Array.select {|e| e["name"] == "sandy" and e["age"] == 21} for some reason I get back the whole array.

In the above I was trying to isolate the offending code. I still seem to be having issues, so full code below. I've done a lot of back and forth with debugging. Some of this code might still be offensive...

    @budgets = Budget.all
    @budgetArray = @budgets.to_a
    @actuals = GeneralLedger.select("account_id, entryDate, sum(amount), CASE WHEN MONTH(entryDate) >= 4 THEN concat(YEAR(entryDate), '') ELSE concat(YEAR(entryDate)-1, '') END as fiscalY").group('account_id, fiscalY').order('account_id').to_a
    @currentYear = 2021
    @numGLYears=2
    #@numGLYears = GeneralLedger.select('count(distinct CASE WHEN MONTH(entryDate) >= 4 THEN concat(YEAR(entryDate), '') ELSE concat(YEAR(entryDate)-1, '') END) as fiscalY FROM general_ledgers').to_s.to_i
    @budgetTable = Array.new
    budgetRow = Array.new
    @budgetArray.each do |b|
        budgetRow.clear
        i=@numGLYears
        #budgetRow.push b.account_id
        while i >= 1
            budgetRow.push getBudget(@budgetArray, @currentYear-i, b.account_id)
            budgetRow.push getActuals(@actuals, @currentYear-i, b.account_id)
            i=i-1
        end
        @budgetTable.push budgetRow
    end
  end

  def getBudget(myArray, year, account)
    rtn = myArray.select{ |e| (e["year"] == year.to_s) and (e["account_id"] == account.to_s)}
    if rtn.nil?
        return '-'
    else
        return rtn
    end
    #get budget if there else '-'
  end
  
  def getActuals(myArray, year, account)
    rtn = myArray.find{ |e| e["year"] == year.to_s and e["account_id"] == account.to_s}
    if rtn.nil?
        return '********************' + year.to_s + account.to_s
    else
        return rtn
    end
  end

Upvotes: 0

Views: 161

Answers (1)

mindlis
mindlis

Reputation: 1677

select returns an array with all the elements that fulfill the condition. Try find which will return the first single item that matches your conditions.

Also make sure your hash has the keys as strings and not symbols, otherwise you won't match any of your conditions. There is a difference between e[:name] and e["name"].

https://apidock.com/ruby/Array/select

https://apidock.com/ruby/Enumerable/find

Upvotes: 2

Related Questions