Having a hard time understanding & implementing some Ruby code - ruby

myitem.inject({}) {|a,b| a[b.one] = b.two; a}
Where:
myitem is a class which holds an array or pair objects (pair objects have two fields in them one and two)
I am not sure what the above code is supposed to do?

Starting with an empty map, set its value for the b.one key to b.two.
In other words, for every item in the "myitem" collection, create a map entry. The key will be an item's "one" value. That map entry's value will be the item's "two" value.
The block given to "inject" receives two parameters. The first is the "accumulator". It's initial value in this case is the empty map passed to "inject". The second parameter is the current item in the collection. In this case, each item in the collection.
The block must return whatever will be used as the next accumulator value, in this case, the map. We want to keep using the same map, so when we're done, the "inject" method will return the map with all the key/value pairs.
Without saving the results of the inject it's a bit worthless.

It's a pedantic way of writing
h = {}
myitem.each { |b| h[b.one] = b.two }
or to be closer to your original code
a = {}
mytem.each { |b| a[b.one] = b.two }
(I personnaly hate this pattern (and people who use it) as it needs the ; a at the end, losing all the functional aspect of inject. (Using a side-effect function inside a 'functional pattern', and then realizing that the later function (a[..]) doesn't return the expecting object is just wrong, IMO).
Inject is normal use to 'fold' a list into a result like
[1,2,3].inject(0) { |sum, x| sum+x }
=> 6 # (0+1+2+3)
here sum is the result of the last call to the block, x is each value on the list and 0 is the initial value of sum.
[2,3].inject(10) { |p,x| p*x }
=> 60 # 10*2*3
etc ...

Hash[my_item.map {|object| [object.one, object.two]}]
is another way to do it.

Related

What is the real use case for .Any() on arrays?

It clearly seems like I miss something very known and common but I can’t get why empty .Any() invocation on array and list differs in result.
As I know when I call .Any() it’s semantically equals of asking: "Does this box contain any items?". So when I write something like this:
List<int> list= new List<int>();
WriteLine(list.Any());//returns false
list.Add(1);
WriteLine(list.Any());//returns true
It expectedly returns false in the first case because list was empty and true when the item was added.
But further if I’ll try to use array instead and this array will be just initialized but empty (without any items) . Any() call will return true:
int[] arr = new int[2];
WriteLine(arr.Any());//returns true despite in has no items
So what’s the point to call empty .Any() on array to check if it has any items inside if it will always return true? Should I avoid use .Any() for such kind of purpose?
What’s the real use case of empty .Any call on array?
When you create an array, all elements are initialized with default values.
So, int[] arr = new int[2] is actually equal to int[] arr = new int[2] { 0, 0 }. That's why .Any() returns true.
Based on your code example, there is no meaningful use case for Any() method on an initialized array.
But, as I mentioned in the comment to your question, if you are calling a method which returns an array, then you can perform an Any() check on the returned array to determine, if it has got any elements.

How to check if nested hash attributes are empty

I have a Hash
person_params = {"firstname"=>"",
"lastname"=>"tom123",
"addresses_attributes"=>
{"0"=>
{"address_type"=>"main",
"catalog_delivery"=>"0",
"street"=>"tomstr",
"city"=>"tomcity"
}
}
}
With person_params[:addresses_attributes], I get:
# => {"0"=>{"address_type"=>"main", "catalog_delivery"=>"0", "street"=>"tomstr", "zip"=>"", "lockbox"=>"", "city"=>"tomcity", "country"=>""}}
1) How can I get a new hash without the leading 0?
desired_hash = {"address_type"=>"main", "catalog_delivery"=>"0", "street"=>"tomstr", "zip"=>"", "lockbox"=>"", "city"=>"tomcity", "country"=>""}
2) How can I check whether the attributes in the new hash are empty?
Answer 1:
person_params[:addresses_attributes]['0']
Answer 2:
hash = person_params[:addresses_attributes]['0']
hash.empty?
This looks just like a params hash from Rails =D. Anyway, it seems that your addresses_attributes contains some nested attributes. This means that what you have in practice is more of an array of hashes than a single hash, and that's what you see right? Instead of it being an actually Ruby Array, it is a hash with the index as a string.
So how do you get the address attributes? Well if you only want to get the first address, here are some ways to do that:
person_params[:addresses_attributes].values.first
# OR
person_params[:addresses_attributes]["0"]
In the first case, we will just take the values from the addreses_attributes hash, which gives us an Array from which we can take the first item. If there are no values in addresses_attributes, then we will get nil.
In the second case, we will just ask for the hash value with the key "0". If there are no values in addresses_attributes, we will get nil with this method also. (You might want to avoid using the second case, if you are not confident that the addresses_attributes hash will always be indexed from "0" and incremented by "1")

Bizzare "attempt to call a table value" in Lua

The following code snippet:
for weight, item in itemlist do
weight_total=weight_total+weight
end
is causing the error "attempt to call table value" on the first line in that snippet. Why?
Itemlist is a table of tables of weights and strings, like such:
local itemlist = {
{4,"weapon_pistol"},
{2,"weapon_357"},
...
Nothing is being called as far as I can tell; why is this error coming up?
The generic for expects 3 arguments: a callable value, some value which is repeatedly passed to it, and the key where the iteration shall start.
Stock lua does not call pairs on the first value passed to for if that's not callable, though some derivatives do.
Thus, you must use ipairs(itemlist), pairs(itemlist), next, itemlist or whatever you want (the last two have identical behavior, and are what most derivatives do).
As an example, an iterator unpacking the value sequence:
function awesome_next(t, k)
k, t = next(t, k)
if not t then return end
return k, table.unpack(t)
end
for k, a, b, c, d in awesome_next, t do
end

Avoid recalculating some values with Enumerable methods

Some methods on Enumerable such as max_by, min_by, or find evaluate some related value for the items iterated, and give back one of the original items. I often want not the original value but the evaluated form. In this example:
max = some_enumerable_object.max_by{|e| some_function(e)}
some_function(max)
max_by selects an item max, but I want the value some_function(max) rather than the max itself. Doing some_function(max) seems waste of calculation because it was already evaluated within the iteration. Is there a way to access some_function(max) without recalculation?
You can call map then max:
max_value = some_enumerable_object.map { |e| some_function(e) }.max
You can always use map to create a sub-array containing your original value, along with your computed value:
max = some_enumerable_object.map{ |o|
[o, some_function(o)]
}.max_by{ |o,e| e }
Once you're done, you can grab your original value, or the result of the function in your max variable.

sorting using weird groovy code

I'm a beginner at groovy and I can't seem to understand this code. Can you please tell me how does this code operate?
def list = [ [1,0], [0,1,2] ]
list = list.sort { a,b -> a[0] <=> b[0] }
assert list == [ [0,1,2], [1,0] ]
what I know is the second line should return the value of 1 because of the spaceship operator but what is the use of that? and what type of sort is this? (there are 6 sort methods in the gdk api and i'm not really sure which is one is used here)
The code is using Collection#sort(Closure). Notice that this method has two variants:
If the closure is binary (i.e. it takes two parameters), sort uses it as the typical comparator interface: it should return an negative integer, zero or a positive integer when the first parameter is less than, equal, or grater than the second parameter respectively.
This is the variant that is being used in that piece of code. It is comparing the elements of the list, which are, in turn, lists, by their first element.
If the closure is unary (i.e. it takes only one parameter) it is used to generate the values that are then going to be used for comparison (in some languages this is called a "key" function).
Therefore, the snippet of code you posted can be rewritten as:
def list = [[1,0], [0,1,2]]
list = list.sort { it[0] } // or { it.first() }
assert list == [[0,1,2], [1,0]]
Notice that using this unary-closure variant is very convenient when you want to compare the elements by some value or some "weight" that is calculated the same way for every element.
The sort in your code snippet uses the comparator argument method call - see http://groovy.codehaus.org/groovy-jdk/java/util/Collection.html#sort(java.util.Comparator)
So, you are sorting the collection using your own comparator. Now the comparator simply uses the first element of the inner collection to decide the order of the outer collection.

Resources