Does Kotlin forEach iterate through an array in real order of array or it may be sometimes in another order? I mean does this always print 1,2,3,...9 or it may print something like this 1,5,3,4,...
val numbers: Array<Int> = array(1,2,3,4,5,6,7,8,9)
numbers.forEach({(number: Int) ->
Log.d(tag,number)
})
Kotlin forEach reference
forEach iterates in order from first to last element; source code:
Collections.kt
/**
* Performs the given [action] on each element.
*/
#kotlin.internal.HidesMembers
public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit {
for (element in this) action(element)
}
Yeah, it keeps real order. Look at implementation:
public inline fun IntArray.forEach(action: (Int) -> Unit): Unit {
for (element in this) action(element)
}
For loop uses iterator of the array, which keeps order too.
These are two separate questions. Yes, as pointed out by the other answers, it keeps the order. But since forEach doesn't print anything, it all depends on the implementation of the printing.
For example, this will not always print the numbers 1 to 10 in order, even though it uses forEach:
fun myPrint(i: Int) = launch { println(i) }
(1..10).forEach { n -> myPrint(n) }
Since we don't know how your Log.d(...) is implemented, we can't be sure.
Related
When you call reversed() on an array in Swift, you get a ReverseCollection which merely wraps the original array with reversed access. Thus this is extremely efficient:
let arr = [1,2,3,4]
for i in arr.reversed() { print(i) }
Nothing actually got reversed except the access; the time complexity of reversed here is O(1). Cool!
But when I index into reversed() by an integer and check Quick Help, it appears I've lost all that efficiency; I'm shown the Sequence reversed() which generates a new array:
let arr = [1,2,3,4]
let i = arr.reversed()[1] // ???? this is a different `reversed()`!
And this seems to be true, because a reversed() array does not, itself, support indexing by number:
let arr = [1,2,3,4]
let rev = arr.reversed()
let i = rev[1] // compile error!
So my question is: is it really true that indexing by number into a reversed() array, as in my second example, loses the efficiency of the ReverseCollection index reversal?
Yes, indexing by Int is causing you to lose your O(1) access into the reversed array. Quite the gotcha!
As you note, reversed() here is an overloaded method; on Array specifically, you have two definitions to choose from:
BidirectionalCollection.reversed(), which returns a ReversedCollection, and
Sequence.reversed(), which turns any sequence into a reversed [Element]
The overloading here is most confusing for Array itself, because it's the only Sequence type such that type(of: x) == type(of: x.reversed()).
The Swift type checker prefers more specific overloads over less-specific ones, so in general, the compiler will use the BidirectionalCollection overload instead of the Sequence one where possible. The rub: BidirectionalCollection has an opaque index type, and cannot be indexed using an Int; when you do index into the collection with an Int, the compiler is instead forced to choose the Sequence overload over the BidirectionalCollection one. This is also why your second code sample fails to compile: Swift code inference does not take into account surrounding context on other lines; on its own, rev is preferred to be a ReversedCollection<Array<Int>>, so attempting to index into it with an Int fails.
You can see this a little more clearly with the following:
func collType1<T: Collection>(_: T) {
print(T.self) // ReversedCollection<Array<Int>>
print(T.Index.self) // Index
}
func collType2<T: Collection>(_: T) where T.Index == Int {
print(T.self) // Array<Int>
print(T.Index.self) // Int
}
let x: [Int] = [1, 2, 3]
collType1(x.reversed())
collType2(x.reversed())
Lest you wonder whether the compiler can optimize around this when the fact of Int-based indexing appears to not have any other side effects, at the time of writing, the answer appears to be "no". The Godbolt output is a bit too long to reproduce here, but at the moment, comparing
func foo1(_ array: [Int]) {
if array.reversed()[100] > 42 {
print("Wow!")
}
}
with
func foo2(_ array: [Int]) {
if array.reversed().dropFirst(100).first! > 42 {
print("Wow!")
}
}
with optimizations enabled shows foo2 performing direct array access
cmp qword ptr [rdi + 8*rax + 24], 43
having optimized away the ReversedCollection wrapper entirely, while foo1 goes through significantly more indirection.
Ferber explained the reason very well.
Here's an ad-hoc solution (which may not be preferred by everyone, because we are extending types from the standard library):
// RandomAccessCollection ensures fast index creation
extension ReversedCollection where Base: RandomAccessCollection {
subscript(_ offset: Int) -> Element {
let index = index(startIndex, offsetBy: offset)
return self[index]
}
}
[1, 2, 3].reversed()[0] // 3
I am new to coding in scala and I am curious about something and it has been hard to find an answer for online. I have this array that takes multiple arguments of different types (:Any)
val arguments= Array("Monday",10,20,Array("test","test2"), if(4 == 4){ "true"})
I iterated and printed the content inside of it. Everything prints properly except the Array at index 3. I get the object memory address I believe, which is understandable-- same thing with Java would happen. But I am curious, how would you access it?
I tried saving the value of arguments(3) in an array (val arr:Array[String] = arguments(3)) but it didn't work because there is a type mismatch (any != Array[String])
Any tips? It might be a gap in my understanding of functional programming.
What you are iterating through is an Array[Any], so you are able to perform functions that are available to an Any type. You can access the items in your array using pattern matching, which uses the unapply methods under the hood to see if it can turn your Any into something more specific:
val arguments= Array("Monday",10,20,Array("test","test2"), if(4 == 4){ "true"})
arguments foreach { arg =>
arg match {
case a:Array[String] => println(s"This is the array: ${a.mkString(",")}, and I can do array functions ${a.contains("test")}")
case _ => println(s"Otherwise I have this: $arg")
}
}
// stdout:
// Otherwise I have this: Monday
// Otherwise I have this: 10
// Otherwise I have this: 20
// This is the array: test,test2, and I can do array functions true
// Otherwise I have this: true
First, a bit of background:
I'm working on one of the Codility lessons, and, even though this is easy to solve, logistically, it is less than easy to solve, performance-wise.
I've been able to boil it down to just this:
public func solution(_ A : inout [Int]) -> Int {
let B = A // Assigning it to a local speeds it up.
return Array<Int>(Set(B)).sorted(by: {$0<$1}).reduce(0) { ($1 == $0 + 1) ? $1 : $0 } + 1
}
However, this is just a WEE bit too slow. I guess that the main reason is that the reduce goes through ALL elements of an array, even though the answer may be early. I may not be able to speed it up.
But I'd like to try. The part that I'm looking at is this:
.reduce(0) { ($1 == $0 + 1) ? $1 : $0 }
I'm wondering if I can make that comparison more efficient.
I have to check if $1 is equal to $0 + 1. I can't avoid that comparison.
The ternary operator is not actually faster than an if clause, but it looks cooler ;).
Is there a higher-performance way to compare two positive integers for equivalence than the basic "==" operator?
BTW: This is not a "do my homework for me" question. It's pretty legit, and these Codility lessons don't give you credit or anything. They are just a fun exercise. I want to know how to do this, as I'm sure I'll need it in the future.
Using the solution suggested by #TNguyen in comments, below piece of code got 100% on both correctness and performance.
You just need to generate the correct Array, containing each Integer in the range [1..(N + 1)] by calling Array(1...A.count+1). Then you sum its elements using reduce(0,+) and finally substract the sum of the elements of the input array A. The difference between the two sums gives the missing element.
public func solution(_ A : inout [Int]) -> Int {
return Array(1...A.count+1).reduce(0,+)-A.reduce(0,+)
}
An even faster solution is to use the mathematical formula1+2+...+n=n(n-1)/2 for the first sum.
public func solution(_ A : inout [Int]) -> Int {
return (A.count+1)*(A.count+2)/2-A.reduce(0,+)
}
100% score in python using an other concept:
def solution(A):
Index=0;
while (Index<len(A)):
while((A[Index]-1) != Index and A[Index]<=len(A)):
Tmp=A[Index]; #Permut
A[Index]=A[Tmp-1];
A[Tmp-1]=Tmp;
Index+=1;
Index=0;
while Index<len(A):
if((A[Index]-1) != Index) :
return Index+1;
else:
Index+=1;
return len(A)+1;
pass
The idea behind is that for a given permutation, each element A[Index]-1 should match to Index except for the missing element. Elements of the array are then permuted until the correspondence is achieved or not achieved when A[Index]>len(A).
In the quest to better understand swift, I'd like to see if there is a more efficient way to write the code below. The code should take the self.categories String, convert it into an array (values separated by commas), and trim each value, before returning the array.
func get_categories() -> Array<String>{
let categories = self.categories!.componentsSeparatedByString(",")
var categories_to_return = Array<String>()
for category in categories {
categories_to_return.append(category.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()))
}
return categories_to_return
}
I've got a suspicion I'm doing something wrong here - perhaps I don't need to create two separate arrays? Perhaps there is another shortcut I've not seen before? Many thanks in advance!
You could use map directly on the result of componentsSeparatedByString, like this, and return it without using another variable:
func get_categories() -> Array<String>{
return self.categories!.componentsSeparatedByString(",").map { $0.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()) }
}
Note: in the map closure, $0 represents the current item from the array of components. It could also be written like this:
func get_categories() -> Array<String>{
return self.categories!
.componentsSeparatedByString(",")
.map { word in word.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()) }
}
Here is a more generic function for general use cases.
func getSplitAndTrimmed(text: String) -> Array<String> {
return text.componentsSeparatedByString(",").map { $0.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()) }
}
The functionality is the same as Eric's wrote.
In Objective-C, if I had the following property:
#property (strong, nonatomic) NSArray * myArray;
A method to return a number of objects in myArray would look like:
- (NSInteger) numberOfObjectsInMyArray
{
return [self.myArray count];
}
This would return either the number of objects in the array, or 0 if myArray == nil;
The best equivalent I can think of for doing this in Swift is:
var myArray: Array<String>?
func numberOfObjectsInMyArray() -> Int
{
return myArray ? myArray!.count : 0
}
So checking the optional array contains a value, and if so unwrap the array and return that value, otherwise return 0.
Is this the correct way to do this? Or is there something simpler?
Try using the nil coalescing operator.
According to the Apple Documentation:
The nil coalescing operator (a ?? b) unwraps an optional a if it contains a value, or returns a default value b if a is nil.
So your function could look like this:
func numberOfObjectsInMyArray() -> Int {
return (myArray?.count ?? 0)
}
I agree with others that this could be a bad idea for a number of reasons (like making it look like there is an array with a count of "0" when there isn't actually an array at all) but hey, even bad ideas need an implementation.
EDIT:
So I'm adding this because two minutes after I posted this answer, I came across a reason for doing exactly what the author wants to do.
I am implementing the NSOutlineViewDataSource protocol in Swift. One of the functions required by the protocol is:
optional func outlineView(_ outlineView: NSOutlineView,
numberOfChildrenOfItem item: AnyObject?) -> Int
That function requires that you return the number of children of the item parameter. In my code, if the item has any children, they will be stored in an array, var children: [Person]?
I don't initialize that array until I actually add a child to the array.
In other words, at the time that I am providing data to the NSOutlineView, children could be nil or it could be populated, or it could have once been populated but subsequently had all objects removed from it, in which case it won't be nil but it's count will be 0. NSOutlineView doesn't care if children is nil - all it wants to know is how many rows it will need to display the item's children.
So, it makes perfect sense in this situation to return 0 if children is nil. The only reason for calling the function is to determine how many rows NSOutlineView will need. It doesn't care whether the answer is 0 because children is nil or because it is empty.
return (children?.count ?? 0) will do what I need. If children is nil it will return 0. Otherwise it will return count. Perfect!
That looks like the simpler way.
The Objective-C code is shorter only because nil is also a form of 0, being a C-based language.
Since swift is strongly typed you don't have such a shorthand. In this specific case it requires a little more effort, but in general it saves you most of the headaches caused by loose typing.
Concerning the specific case, is there a reason for making the array optional in the first place? You could just have an empty array. Something like this might work for you:
var myArray: Array<String> = []
func numberOfObjectsInMyArray() -> Int {
return myArray.count
}
(Source for this information)
How about using optional for return value?
var myArray: Array<String>?
func numberOfObjectsInMyArray() -> Int? {
return myArray?.count
}
I think that this way is safer.
(Source for this information)