Do maps in groovy maintain order in which the data has been provided? I.e. when iterating over keys, will the order be preserved at all times?
farms = [Idaho: ["Duck", "Dog"], Ohio: ["Chicken", "Duck"], "New Mexico": ["Dog", "Cow"]]
Yes. When you use the map literal syntax in groovy it creates an instance of a LinkedHashMap, which will maintain order. This can be seen in this ideone.
Just a Note
In my experience (not always, mind you) if you need to maintain the order of a Map then you might not be using it in the correct way. There aren't many real use cases that call for this type of map.
Related
I use Array.wrap(x) all the time in order to ensure that Array methods actually exist on an object before calling them.
What is the best way to similarly ensure a Hash?
Example:
def ensure_hash(x)
# TODO: this is what I'm looking for
end
values = [nil,1,[],{},'',:a,1.0]
values.all?{|x| ensure_hash(x).respond_to?(:keys) } # true
The best I've been able to come up with so far is:
Hash::try_convert(x) || {}
However, I would prefer something more elegant.
tl; dr: In an app with proper error handling, there is no "easy, care-free" way to handle something that may or may not be hashy.
From a conceptual standpoint, the answer is no. There is no similar solution as Array.wrap(x) for hashes.
An array is a collection of values. Single values can be stored outside of arrays (e.g. x = 42) , so it's a straight-forward task to wrap a value in an array (a = [42]).
A hash is a collection of key-value pairs. In ruby, single key-value pairs can't exist outside of a hash. The only way to express a key-value pair is with a hash: h = { v: 42 }
Of course, there are a thousand ways to express a key-value pair as a single value. You could use an array [k, v] or a delimited string `"k:v" or some more obscure method.
But at that point, you're no longer wrapping, you're parsing. Parsing relies on properly formatted data and has multiple points of failure. No matter how you look at it, if you find yourself in a situation where you may or may not have a hash, that means you need to write a proper chunk of code for data validation and parsing (or refactor your upstream code so that you can always expect a hash).
I have this parameter as an array. The array is big, 100 cells. It is a parameter that can be initiated in omnet.ini file. The cells with even numbers should get value A and odd numbers should get value B. How can I do this in an automated manner?
Is there a way besides having all odd and even indices initiated one by one manually?
Wildcards can be useful but I do not know how to use them to separate odd and even indices.
Thanks.
You can access the actual module index with the index operator. Combining this with the conditional operator ?: you can easily define the value:
**.myModule[*].myParameter = index % 2 == 0 ? "A" : "B"
I'm not aware of any feature like this. There are a number of work-arounds you could use:
Provide two parameters and select the correct one in code
Use the volatile keyword (probably not appropriate here)
Put the entire thing in your .ini file
I'd personally implement the first approach, that way you can use the wildcard to pass both parameters ([*].myNode.parameterEven and [*].myNode.parameterUneven) and then set the correct values in your array in a for loop.
However, you could also use the volatile keyword in your NED file, see the manual for more details. However, this approach mostly works well if you have different parameters depending on which node you are assigning it to. For this case I think the first approach is better.
The last alternative is just putting the entire thing in your .ini file, which may be useful if you want to parameterize the array later.
The difference between Enumerable#each and Enumerable#map is whether it returns the receiver or the mapped result. Getting back to the receiver is trivial and you usually do not need to continue a method chain after each like each{...}.another_method (I probably have not seen such case. Even if you want to get back to the receiver, you can do that with tap). So I think all or most cases where Enumerable#each is used can be replaced by Enumerable#map. Am I wrong? If I am right, what is the purpose of each? Is map slower than each?
Edit:
I know that there is a common practice to use each when you are not interested in the return value. I am not interested in whether such practice exists, but am interested in whether such practice makes sense other than from the point of view of convention.
The difference between map and each is more important than whether one returns a new array and the other doesn't. The important difference is in how they communicate your intent.
When you use each, your code says "I'm doing something for each element." When you use map, your code says "I'm creating a new array by transforming each element."
So while you could use map in place of each, performance notwithstanding, the code would now be lying about its intent to anyone reading it.
The choice between map or each should be decided by the desired end result: a new array or no new array. The result of map can be huge and/or silly:
p ("aaaa".."zzzz").map{|word| puts word} #huge and useless array of nil's
I agree with what you said. Enumerable#each simply returns the original object it was called on while Enumerable#map sets the current element being iterated over to the return value of the block, and then returns a new object with those changes.
Since Enumerable#each simply returns the original object itself, it can be very well preferred over the map when it comes to cases where you need to simply iterate or traverse over elements.
In fact, Enumerable#each is a simple and universal way of doing a traditional iterating for loop, and each is much preferred over for loops in Ruby.
You can see the significant difference between map and each when you're composing these enumaratiors.
For example you need to get new array with indixes in it:
array.each.with_index.map { |index, element| [index, element] }
Or for example you just need to apply some method to all elements in array and print result without changing the original array:
m = 2.method(:+)
[1,2,3].each { |a| puts m.call(a) } #=> prints 3, 4, 5
And there's a plenty another examples where the difference between each and map is important key in the writing code in functional style.
Whenever I see Ruby code that says:
arrayNames.collect { ... }
I forget what collect is and have to look up what it is, and find that it is the same as map().
Map, I can understand, mapping 1 byte to a pixel, and function is to map an x to a y, a 2 to a 4, a 5 to a 25, etc. But where does the name "collect" come from? Maybe that will help to remember what a "collect" method is.
It comes from Smalltalk old days. Smalltalk used collect and select instead of map and filter (as used in many other languages) for iterating on its collections.
To add to the other answers, it is kind of an inside-joke in Smalltalk:
inject:into:
collect:
select:
reject:
detect:
Spot the pattern?
kriss is right that the method name has its origins in Smalltalk but to help remember what it does when you see it used you can think of it as "collecting the results from the block in a new array".
def add app
#has_app[app] = true
#apps << app
end
In the code above, instead of using
#has_app[app] = true
to keep track of the presence of 'app', couldn't we also say:
#apps.include? (app)
and do away with #has_app?
I'm trying to understand why this separate variable is needed here at all (?).
If this is the extent of the code, then yes, you could simply use the include? method. This is redundant data. It could be, though, that this hash of booleans has some different meaning that's not clear from these lines of code.
There would be a performance difference (for large lists), as a hash lookup is faster than an array lookup as the size increases. (You'd need to double check Ruby specifics, if this is important).
Methods with question-marks just check the state of variable instead of modifying it. Thus #apps.include?(app) would return either true or false depending on the array having the given object.
Yes, I agree with you. #has_app? is not a must. The only reason I can think of why the original coder used it is for performance's sake. Note that :
#has_app is a Hash
#app is an Array.