0

i'm new to ruby and i want to instersect two arrays

validAccountTypes = [
    'Asset' => 'Asset',
    'Liability' => 'Liability',
    'Equity' => 'Equity',
    'Income' => 'Income',
    'CostOfSales' => 'Cost of Sales',
    'Expense' => 'Expenses',
    'OtherIncome' => 'Other Income',
    'OtherExpense' => 'Other Expenses',
]

types = [
    'Asset',
    'Other Income',
    'Other Expenses',
]

I want a result of valid Accounts with keys base on array types. The output would be

[{"Asset"=>"Asset", "OtherIncome"=>"Other Income", "OtherExpense" => "Other Expenses"}]

Is it possible without a loop?

2 Answers 2

2

Here's a rewrite of your variables with a few changes:

  • Underscore variable names
  • valid_account_types is now a hash instead of an array containing a hash.
  • Some typos corrected so that the members of types match keys of valid_account_types.

    valid_account_types = {
      'Asset' => 'Asset',
      'Liability' => 'Liability',
      'Equity' => 'Equity',
      'Income' => 'Income',
      'CostOfSales' => 'Cost of Sales',
      'Expense' => 'Expenses',
      'OtherIncome' => 'Other Income',
      'OtherExpenses' => 'Other Expenses',
    }
    
    types = [
      'Asset',
      'OtherIncome',
      'OtherExpenses',
    ]
    

Given that setup, if you are using Rails, you can get the result you want using Hash#slice, like this:

> valid_account_types.slice(*types)
=> {"Asset"=>"Asset", "OtherIncome"=>"Other Income", "OtherExpenses"=>"Other Expenses"}

Note that Hash#slice does not exist in Ruby itself. If you want to do this in plain-old Ruby, you could check out the implementation in i18n:

class Hash
  def slice(*keep_keys)
    h = self.class.new
    keep_keys.each { |key| h[key] = fetch(key) if has_key?(key) }
    h
  end
end
Sign up to request clarification or add additional context in comments.

Comments

0

Your first array isn't an array, it's actually a hash (notice the surrounding braces, rather than brackets):

validAccountTypes = {
    'Asset' => 'Asset',
    'Liability' => 'Liability',
    'Equity' => 'Equity',
    'Income' => 'Income',
    'CostOfSales' => 'Cost of Sales',
    'Expense' => 'Expenses',
    'OtherIncome' => 'Other Income',
    'OtherExpense' => 'Other Expenses',
}

You can get the keys on the hash and intersect it with your array:

common_keys = validAccountTypes.keys & types

Then you can select only those keys:

# Hash#slice works in Rails: 
validAccountTypes.slice(*common_keys)

# Otherwise use Hash#select:
validAccountTypes.select { |key, value| common_keys.include?(key) }

Note that in your example, your hash keys include 'OtherIncome' and 'OtherExpense', but your types array includes 'Other Income' and 'Other Expenses'. Your array values should match the keys from the hash.

2 Comments

"Your first array isn't an array, it's actually a hash" – It's an array with a single element which is a hash.
Oh wow, you're right! Didn't realize the syntax worked that way.

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.