简体   繁体   中英

How to intersect arrays in ruby?

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?

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM