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

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.

Related

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")

How to count the elements of an array inside an array?

I have a method which returns the number of hotels from a webpage:
hotel_count = self.getHotelsList.values
The output of this method is:
[["hotel_0", "hotel_1", "hotel_2", "hotel_3", "hotel_4", "hotel_5", "hotel_6", "hotel_7", "hotel_8", "hotel_9", "hotel_10", "hotel_11", "hotel_12", "hotel_13", "hotel_14", "hotel_15", "hotel_16", "hotel_17", "hotel_18", "hotel_19", "hotel_20", "hotel_21", "hotel_22", "hotel_23", "hotel_24", "hotel_25", "hotel_26", "hotel_27", "hotel_28", "hotel_29", "hotel_30", "hotel_31", "hotel_32", "hotel_33", "hotel_34", "hotel_35", "hotel_36", "hotel_37", "hotel_38", "hotel_39", "hotel_40"]]
I want to know the length of this array, but if I write
hotel_count = self.getHotelsList.values.length
The length is 1. How can I get a length of 41, which is the one I'm expecting?
Thanks
The array you are showing is nested inside another array. So the outer array is of length 1, the inner array is what you want.
To get it you have to first get the first element of the outer array using [0] or first
testList[0].length
testList.first.length
I am not sure why your getHotelsList method returns a nested array, it doesn't appear to need it.
hotel_count = getHotelsList.values.first.length
You can also do it with [0], but first is faster.
Two notes:
You don't need self at the beginning.
It is a bad habit to use camel case for method names in Ruby. it should better be get_hotels_list.
You could convert that into a single array with flatten:
hotel_count = self.getHotelsList.values.flatten.size

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.

Having a hard time understanding & implementing some Ruby code

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.

Ruby Array find_first object?

Am I missing something in the Array documentation? I have an array which contains up to one object satisfying a certain criterion. I'd like to efficiently find that object. The best idea I have from the docs is this:
candidates = my_array.select { |e| e.satisfies_condition? }
found_it = candidates.first if !candidates.empty?
But I am unsatisfied for two reasons:
That select made me traverse the whole array, even though we could have bailed after the first hit.
I needed a line of code (with a condition) to flatten the candidates.
Both operations are wasteful with foreknowledge that there's 0 or 1 satisfying objects.
What I'd like is something like:
array.find_first(block)
which returns nil or the first object for which the block evaluates to true, ending the traversal at that object.
Must I write this myself? All those other great methods in Array make me think it's there and I'm just not seeing it.
Either I don't understand your question, or Enumerable#find is the thing you were looking for.
use array detect method if you wanted to return first value where block returns true
[1,2,3,11,34].detect(&:even?) #=> 2
OR
[1,2,3,11,34].detect{|i| i.even?} #=> 2
If you wanted to return all values where block returns true then use select
[1,2,3,11,34].select(&:even?) #=> [2, 34]
Guess you just missed the find method in the docs:
my_array.find {|e| e.satisfies_condition? }
Do you need the object itself or do you just need to know if there is an object that satisfies.
If the former then yes: use find:
found_object = my_array.find { |e| e.satisfies_condition? }
otherwise you can use any?
found_it = my_array.any? { |e| e.satisfies_condition? }
The latter will bail with "true" when it finds one that satisfies the condition.
The former will do the same, but return the object.

Resources