How does Iterator::all work? - rust

I do not understand iter().all. This code from the docs works:
let d = [2, 3, 4, 6, 8];
assert!(a.iter().all(|x| *x > 0));
Why does the one below not work?
for x in d.iter().all(|x| *x > 2) {
println!("{} is bigger than 2", x);
}

all tests that the given predicate holds true for all elements. It returns false as soon as it finds an element that does not match the predicate, or true if all elements match. It is not used to iterate over matching elements. You should probably use filter for that. See the Iterator::all documentation.

Related

What is the difference between any and find in groovy?

I am trying to get the set values from closure in groovy:
myList(1, 2, 3).any { it > 2 }
myList(1, 2, 3).find { it > 2 }
So not able to figure out, which one to use and better.
any returns boolean - true if any of the elements on the list matches the closure condition, while find returns first element that meets the criteria in closure being passed.
If you need to know if there're elements matching certain criteria, use any, if you need only a single element (the first one) use, find, if you need all the elements that matches the closure passed use findAll.
Example:
assert [1, 2, 3].any { it > 1 }
assert [1, 2, 3].find { it > 1 } == 2
assert [1, 2, 3].findAll { it > 1 } == [2, 3]

Underscore GroupBy Sort

I have a question regarding programming in function style.
I use underscore.js library.
Let's consider some use-case. I have an array of some labels with repetitions I need to count how many occurrences of each label is in array and sort it according to the number of occurrences.
For counting, how many labels I can use countBy
_.countBy([1, 2, 3, 4, 5], function(num) {
return num % 2 == 0 ? 'even': 'odd';
});
=> {odd: 3, even: 2}
But here, as result I have a hash, which doesn't have meaning for order, so there is no sort. So here, I need to convert the hash to array then to sort it and convert backward to hash.
I am pretty sure there is an elegant way to do so, however I am not aware of it.
I would appreciate any help.
sort it and convert backward to hash.
No, that would loose the order again.
You could use
var occurences = _.countBy([1, 2, 3, 4, 5], function(num) {
return num % 2 == 0 ? 'even': 'odd';
});
// {odd: 3, even: 2}
var order = _.sortBy(_.keys(occurences), function(k){return occurences[k];})
// ["even", "odd"]
or maybe just
_.sortBy(_.pairs(occurences), 1)
// [["even", 2], ["odd", 3]]

Collect only if result is not null

I have a collection and I'm wanting to find certain elements and transform them. I can do this in two closures but I was wondering if it is possible with only one?
def c = [1, 2, 3, 4]
def result = c.findAll {
it % 2 == 0
}
result = result.collect {
it /= 2
}
My true use case is with Gradle, I want to find a specific bunch of files and transform them to their fully-qualified package name.
You can use findResults:
def c = [1, 2, 3, 4]
c.findResults { i ->
i % 2 == 0 ? // if this is true
i / 2 : // return this
null // otherwise skip this one
}
Also, you will get [] in case none of the elements satisfies the criteria (closure)

How to get all elements from a list without the last element?

The following Groovy code
lines = ['0','1','2','3','4','5']
println lines[1..lines.size()-1]
println lines[1..-1]
println lines[1..<lines.size()-1]
println lines[1..<-1]
println lines[1..<-2]
println lines[1..-2]
produces this output:
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 3, 4]
[1, 0]
[1, 2, 3, 4, 5]
[1, 2, 3, 4]
Since -1 is the index of the last element in the list, the first two make sense (ranges in Groovy include the end element instead of omitting it as everywhere else in Java :-( )
Line #3 is the desired output (list without first and last element).
I'm worried about the output #4: Why do I get [1, 0] for 1..-1?
Also [1, 2, 3, 4, 5] for the range 1..<-2 seems wrong.
Why does that happen?
The best way to take all elements but the last one, in my opinion, is to use the take method:
def list = ['a', 'b', 'c']
assert list.take(list.size() - 1) == ['a', 'b']
It behaves properly in the corner case where size == 1:
def list = ['one']
assert list.take(list.size() - 1) == []
Though I'd prefer it to throw an exception in the case size == 0, but the behavior is not that bad:
def list = []
assert list.take(list.size() - 1) == []
You can also use list[0..<list.size()-1] (your third example) and it will behave the same except for the empty list, in which case it will throw an ArrayIndexOutOfBoundsException, but i think is not as readable as the take counterpart.
Another acceptable solution is using list[0..-2] (your last example), which i think looks much more elegant, but unfortunately breaks when size == 1 with an ArrayIndexOutOfBoundsException.
In your examples (i'll assume that you meant to use 0 as the starting index instead of 1 if you wanted to include all elements but the last one):
lines[0..lines.size()-1] is equivalent to lines[0..-1] because the getAt(Range) method of lists will treat ranges with negative indexes the same way asgetAt(Integer) does, i.e. as accessing the (list.size() + negativeIndex)'th element of the list. Therefore list[0..-1] is the same as saying "from first element to last" and it's the same as copying the list; and list[-1..0] is the same as "from last to first" and it's equivalent to list.reverse() :)
The problem with the other non-inclusive range example is that the non-inclusive ranges are being evaluated before the list access and they evaluate to an incorrect inclusive range. For example, 0..<-2 evaluates to 0..-1, and that's why it's returning all the elements. 0..<-1 evaluates to 0..0 and it returns only the first element.
Notice that the empty range is a special case. It's denoted as 0..<0 and it doesn't have an inclusive equivalent (so Groovy won't do any magic conversion here). And that's why list[0..<list.size()-1] works when size == 1 (the range evaluates to the empty range) while list[0..-2] doesn't :)
Maybe this has changed since epideman wrote his answer, but you can get the whole list without the last element with 0..<-1:
assert ["foo"][0..<-1] == []
assert ["foo", "bar"][0..<-1] == ["foo"]
assert ["foo", "bar", "baz"][0..<-1] == ["foo", "bar"]
// blows up if empty, here take is better
assert [][0..<-1] == [] // BOOM
// if you want null safe, use take
assert [].take(-1) == []
This is with groovy 2.2.1.
Since Groovy 2.4 you can use the init() method:
lines = ['0','1','2','3','4','5']
assert lines.init() == ['0','1','2','3','4']

Groovy - Get first elements in multi-dimensional array

I have a groovy list of lists i.e.
list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]]
I would like to get a subset of just the first elements of each array
sublist = [2, 1, 1]
I know I can loop through the and just get the first element and add, but I am trying to avoid this since I have a huge array of values. I'm trying to avoid this solution
def sublist = []
list.each {
sublist.add(it[0])
}
Thanks.
A more readable version:
list*.first()
You could try:
list.collect { it[0] }
Although that still involves iteration (although somewhat hidden). However, it's likely that any solution is going to involve iteration somewhere down the line, whether it be written by you or the library/API method you call.
If you're worried about copying the data, a better approach might be to create a custom iterator, rather than copying the data into another list. This is a great approach if you only need to traverse through the sublist once. Also, if you don't traverse to the end of the sublist, you haven't wasted any effort on the elements you never processed. For example:
bigList = [[2, 0, 1], [1, 5, 2], [1, 0, 3]]
bigListIter = bigList.iterator()
firstOnlyIter = [
hasNext: { -> bigListIter.hasNext() },
next: { -> bigListIter.next().first() }
] as Iterator
for (it in firstOnlyIter) {
println it
}
You can always turn the iterator back into a list with Iterator.toList().

Resources