Remove item from enum ruby - ruby-on-rails

I have this code here that gets a region and add to my variable "regions".
So let' say it has: XYZ, DDA, BBB, ....
Let's say I want to get everything but DDA.
How can I do that.
Code:
def supported_regions(partition)
if ##supported_regions_by_partition_cache[partition].nil?
regions = xrp_supported_regions({ignore_build_status: IGNORE_BUILD_STATUS})
.map { |region| rip_helper.get_region(region) }
.select { |region| region.arn_partition == partition }
.sort_by(&:region_name)
.map(&:airport_code)
##supported_regions_by_partition_cache[partition] = regions
else
regions = ##supported_regions_by_partition_cache[partition]
end
regions
end
I already tried doing:
regions.delete('DDA')
also
.reject {|s| 'DDA' != s }
Not sure how I can do this. I am very new on Ruby.

You can use the select method and replace this line:
FROM
.select { |region| region.arn_partition == partition }
TO
.select { |region| region.arn_partition == partition && region.region_name != "DDA" }

Related

add contents of 1 hash into another

I have a parent hash which changes and I want to ensure that the child hashes take these changes but also retain keys that they had before and those should not be lost
These are the sample hashes that I have
one = {"endpoints"=>["get_route"], "features"=>["channel_selection"], "get_route"=>{"output"=>["total_length", "seca_length"], "options"=>["panama", "abcd"]}}
other = {"endpoints"=>["get_route"], "features"=>["channel_selection"], "get_route"=>{"output"=>["total_length", "seca_length"], "options"=>["panama", "suez", "kiel"]}}
I want the other hash to now look like
other = {"endpoints"=>["get_route"], "features"=>["channel_selection"], "get_route"=>{"output"=>["total_length", "seca_length"], "options"=>["panama", "abcd", suez", "kiel"]}}
I have tried the following code but it is not working
result = propogate_changes(one, other)
def propogate_changes(one, other)
one_keys = one.keys
other_keys = other.keys
combined = Hash.new
unique_keys = one_keys.concat(other_keys).uniq
unique_keys.each do |key|
if(one[key].is_a?(Array)) then
# if(other[key] == nil) then
# combined[key] = one[key]
# else
combined[key] = one[key].concat(other[key]).uniq
# end
else
combined[key] = add_allowance(one[key], other[key])
end
end
return combined
end
The above code fails when a key is present in one but missing in another
I also tried merge, deep_merge, reverse_merge but they all overwrite my other hash with one hash but none of them retain the original data.
Any advise on this will be appreciated
Try this custom merge logic.
def find_missing_items_in_arr(arr1, arr2)
arr1_size = arr1.size
arr2_size = arr2.size
if (arr1_size == arr2_size) && (arr1 & arr2).size == arr1_size
return [] # Same array
end
arr2 - arr1
end
def custom_merge(target_hash, source_hash)
# If you want to preserve frozen state of entries, please use `clone`
duped_target_hash = target_hash.dup
source_hash.each do |k, v|
unless duped_target_hash.key?(k)
duped_target_hash[k] = v
next
end
case v
when Array
missing_items_in_arr = find_missing_items_in_arr(duped_target_hash[k], v)
if missing_items_in_arr.size > 0
duped_target_hash[k] += missing_items_in_arr
end
when Hash
duped_target_hash[k] = custom_merge(duped_target_hash[k], v)
else
# Nothing to do here
end
end
duped_target_hash
end
Usage
one = {
"endpoints"=>["get_route"],
"features"=>["channel_selection"],
"get_route"=> {
"output"=> ["total_length", "seca_length"],
"options"=> ["panama", "abcd"]
}
}
other = {
"endpoints"=>["get_route"],
"features"=>["channel_selection"],
"get_route"=> {
"output"=> ["total_length", "seca_length"],
"options"=> ["panama", "suez", "kiel"]
}
}
rs_hash = custom_merge(other, one)
puts rs_hash
Note: Rails provides a deep_merge but this can be used outside Rails. I have tested and it returns your desired output. Also it handles more nested entries like
one = {
"endpoints"=>["get_route"],
"features"=>["channel_selection"],
"get_route"=> {
"output"=> ["total_length", "seca_length"],
"options"=> ["panama", "abcd"],
"custom_options" => {
"custom_output" => ["abc"],
"custom_input" => ["xyz" ]
}
}
}
other = {
"endpoints"=>["get_route"],
"features"=>["channel_selection"],
"get_route"=> {
"output"=> ["total_length", "seca_length"],
"options"=> ["panama", "suez", "kiel"],
"custom_options" => {
"custom_output" => ["abc", "def"]
}
}
}
Hope this helps.

Deleting nested hash elements based on those elements' properties

I have some data:
data = {
"total_records"=>3,
"records"=>
[{"title"=>"Val1",
"coins"=>1},
{"title"=>"Val2",
"coins"=>1},
{"title"=>"Val3",
"coins"=>1}]
}
How would I go about deleting the records that have title = 'Val1'||'Val2'?
I tried something along these lines:
#data.records.each_value do |e|
if exceptions.include?(e.title)
delete #envelopes.records.e
end
end
But I get a no method error on #data.records.
So simple
data['records'].delete_if{ |h| %w(Val1 Val2).include?(h['title']) }
You can also do this:
data['records'].delete_if{ |h| (h['title'] == 'Val1') || (h['title'] == 'Val2') }

get models name and count

I have this in models_name:
model_names = Object.constants.collect { |sym| Object.const_get(sym) }.select { |constant| constant.class == Class && constant.include?(Mongoid::Document) }.collect { |klass| klass.name }
the result is:
["Model_name1","Model_name2","Model_name3"]
I need something like:
[{"Model1":"Count"},{"Model2":"Count"},{"Model3":"Count"}]
I need show in a chart all models and object counter inside each model is working with morris.js
You can see the example:
http://jsbin.com/uzosiq/2/embed?javascript,live
Thank you very much!
that last one:
collect { |klass| klass.name }
rewrite it as
collect { |klass| [klass.name, klass.count] }
this should return an array of arrays of 2 elements (classname and count). If the variable to which this is assigned is called a, just do this:
Hash[a]
now you have a hash at your disposal. Now you can do this:
Hash[a].map do |k, v|
{k => v}
end
and now you have an array of hashes of only one key-value assoc each. Which I think it is what you want.
module Foo
end
class Bar
include Foo
end
1.upto(5) { Bar.new }
model_names = Object.constants.collect { |sym| Object.const_get(sym) }.
select { |constant| constant.class == Class && constant.include?(Foo) }.
inject({}) do |m,klass|
m.update klass.name => ObjectSpace.each_object(klass).to_a.size
end
p model_names
{"Bar"=>5}
Will work only on MRI based rubies, so no jRuby nor Runbinius.
Here is a live demo

Searching for a specifc item in array

I have an array of objects and I need to find the last element that matches a specific condition. I tried to do it with each_reverse, but it ended up with too much of a code:
matching_item = nil
items.reverse_each do |item|
if (item.type_id == 10)
matching_item = item
break
end
end
Is it possible to make it shorter?
Try:
matching_item = items.reverse.find{ |i| i.type_id == 10 }
I would probably use Array#select and return the last match:
matching_item = items.select {|i| i.type_id == 10}.last
Leave off the .last if you decide you want all matches:
matching_items = items.select {|i| i.type_id == 10}
items.reverse_each.detect{|item| iterm.type_id == 10}
#or
items[items.rindex{|item| item.type_id == 10}]

What is an elegant way to replace an element of an array based on a match criteria?

I am using the following logic to update a list item based on a criteria.
def update_orders_list(order)
#orders.delete_if{|o| o.id == order.id}
#orders << order
end
Ideally, I would have preferred these approaches:
array.find_and_replace(obj) { |o| conditon }
OR
idx = array.find_index_of { |o| condition }
array[idx] = obj
Is there a better way?
array.map { |o| if condition(o) then obj else o }
maybe?
As of 1.8.7, Array#index accepts a block. So your last example should work just fine with a minor tweak.
idx = array.index { |o| condition }
array[idx] = obj

Resources