Sort an unsorted array with Closures - swift2

let unsortedArray = [98,23,643,678,2,568,1,234,556,4] {
(first:Int , second:Int) -> Bool in
if first < second {
return true
} else{
return false
}
}
Above code is to sort an unsorted array with Swift 2 and Xcode 7.3.
I want to know how can i print the result?

The syntax is:
let unsortedArray = [98, 23, 643, 678, 2, 568, 1, 234, 556, 4]
let sortedArray = unsortedArray.sort() { (first: Int, second: Int) -> Bool in
if first < second {
return true
} else {
return false
}
}
print("\(sortedArray)")
Note, in Swift 2.3 that's sort, but in Swift 3, it is now called sorted.
By the way, this can be simplified:
let sortedArray = unsortedArray.sort { (first: Int, second: Int) -> Bool in
return first < second
}
Or, further simplified to use anonymous closure arguments:
let sortedArray = unsortedArray.sort {
return $0 < $1
}
Which because there is a single expression inside the closure, you can further simply to:
let sortedArray = unsortedArray.sort { $0 < $1 }
Or, further simplified to:
let sortedArray = unsortedArray.sort(<)
Or, because the elements of the array, Int types, conform to Comparable, you can omit the closure entirely and use a different sort method that takes no parameters at all:
let sortedArray = unsortedArray.sort()
Note, this requires that the elements of the array have:
The less-than operator (func <) defined in
the Comparable conformance is a
strict weak ordering
over the elements in self.

Related

How does compareBy work in kotlin using a boolean expression

I know from official documentation that compareBy
creates a comparator using the sequence of functions to calculate a result of comparison. The functions are called sequentially, receive the given values a and b and return Comparable objects.
I know how this must be done for normal attributes like the integer value here, but how are boolean conditions handled by compareBy?
In this example, I intended to keep all 4's at the top of the list and then sort in ascending order of values, but I am not sure how this boolean expression helps me do this!
fun main(args: Array<String>) {
var foo = listOf(2, 3, 4, 1, 1, 5, 23523, 4, 234, 2, 2334, 2)
foo = foo.sortedWith(compareBy({
it != 4
},{
it
}))
print(foo)
}
Output
[4, 4, 1, 1, 2, 2, 2, 3, 5, 234, 2334, 23523]
Boolean is Comparable
public class Boolean private constructor() : Comparable<Boolean>
So when you're returning it != 4 in compareBy you're using Boolean's sort order i.e. false < true. Your expression is false only when it == 4, and indeed you can see the 4s as the first elements in the output.
Your code provides two selectors as a vararg to compareBy :
foo.sortedWith(
compareBy(
{ it != 4 },
{ it }
)
)
Digging into the sources we have a Comparator for any two values a and b built up: Comparator { a, b -> compareValuesByImpl(a, b, selectors) }
and finally:
private fun <T> compareValuesByImpl(a: T, b: T, selectors: Array<out (T) -> Comparable<*>?>): Int {
for (fn in selectors) {
val v1 = fn(a)
val v2 = fn(b)
val diff = compareValues(v1, v2)
if (diff != 0) return diff
}
return 0
}
The last code snippet demonstrates that if all selectors have the same diff, a and b are considered equal otherwise the first selector with diff != 0 wins.
Booleans are comparable. When comparing 4 with any other value, say 2, you will have:
4 != 4 false
2 != 4 true
diff = false.compareTo( true ) == -1
and so, for sorting, 4 is "less" then any value that is not 4

One-liner to generate Powerball picks in Swift?

With the U.S.'s large $1.5 Billion lottery this week, I wrote a function in Ruby to make Powerball picks. In Powerball, you choose 5 numbers from the range 1..69 (with no duplicates) and 1 number from the range 1..26.
This is what I came up with:
def pball
Array(1..69).shuffle[0..4].sort + [rand(1..26)]
end
It works by creating an array of integers from 1 to 69, shuffling that array, choosing the first 5 numbers, sorting those, and finally adding on a number from 1 to 26.
To do this in Swift takes a bit more work since Swift doesn't have the built-in shuffle method on Array.
This was my attempt:
func pball() -> [Int] {
let arr = Array(1...69).map{($0, drand48())}.sort{$0.1 < $1.1}.map{$0.0}[0...4].sort()
return arr + [Int(arc4random_uniform(26) + 1)]
}
Since there is no shuffle method, it works by creating an [Int] with values in the range 1...69. It then uses map to create [(Int, Double)], an array of tuple pairs that contain the numbers and a random Double in the range 0.0 ..< 1.0. It then sorts this array using the Double values and uses a second map to return to [Int] and then uses the slice [0...4] to extract the first 5 numbers and sort() to sort them.
In the second line, it appends a number in the range 1...26. I tried adding this to the first line, but Swift gave the error:
Expression was too complex to be solved in reasonable time; consider
breaking up the expression into distinct sub-expressions.
Can anyone suggest how to turn this into a 1-line function? Perhaps there is a better way to choose the 5 numbers from 1...69.
Xcode 8.3 • Swift 3.1
import GameKit
var powerballNumbers: [Int] {
return (GKRandomSource.sharedRandom().arrayByShufflingObjects(in: Array(1...69)) as! [Int])[0..<5].sorted() + [Int(arc4random_uniform(26) + 1)]
}
powerballNumbers // [5, 9, 62, 65, 69, 2]
Swift 2.x
import GameKit
var powerballNumbers: [Int] {
return (GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(Array(1...69)) as! [Int])[0...4].sort() + [Int(arc4random_uniform(26).successor())]
}
powerballNumbers // [21, 37, 39, 42, 65, 23]
I don't find the "one-liner" concept very compelling. Some languages lend themselves to it; others don't. I would suggest giving Swift a shuffle method to start with:
extension Array {
mutating func shuffle () {
for var i = self.count - 1; i != 0; i-- {
let ix1 = i
let ix2 = Int(arc4random_uniform(UInt32(i+1)))
(self[ix1], self[ix2]) = (self[ix2], self[ix1])
}
}
}
But since I made this mutating, we still need more than one line to express the entire operation because we have to have a var reference to our starting array:
var arr = Array(1...69)
(1...4).forEach {_ in arr.shuffle()}
let result = Array(arr[0..<5]) + [Int(arc4random_uniform(26)) + 1]
If you really insist on the one-liner, and you don't count the code needed to implement shuffle, then you can do it, though less efficiently, by defining shuffle more like this:
extension Array {
func shuffle () -> [Element] {
var arr = self
for var i = arr.count - 1; i != 0; i-- {
let ix1 = i
let ix2 = Int(arc4random_uniform(UInt32(i+1)))
(arr[ix1], arr[ix2]) = (arr[ix2], arr[ix1])
}
return arr
}
}
And here's your one-liner:
let result = Array(1...69).shuffle().shuffle().shuffle().shuffle()[0..<5] + [Int(arc4random_uniform(26)) + 1]
But oops, I omitted your sort. I don't see how to do that without getting the "too complex" error; to work around that, I had to split it into two lines:
var result = Array(1...69).shuffle().shuffle().shuffle().shuffle()[0..<5].sort(<)
result.append(Int(arc4random_uniform(26)) + 1)
How about this:
let winningDraw = (1...69).sort{ _ in arc4random_uniform(2) > 0}[0...4].sort() + [Int(arc4random_uniform(26)+1)]
[edit] above formula wasn't random. but this one will be
(1...69).map({Int(rand()%1000*70+$0)}).sort().map({$0%70})[0...4].sort() + [Int(rand()%26+1)]
For the fun of it, a non-GameplayKit (long) one-liner for Swift 3, using the global sequence(state:next:) function to generate random elements from the mutable state array rather than shuffling the array (although mutating the value array 5 times, so some extra copy operations here...)
let powerballNumbers = Array(sequence(state: Array(1...69), next: {
(s: inout [Int]) -> Int? in s.remove(at: Int(arc4random_uniform(UInt32(s.count))))})
.prefix(5).sorted()) + [Int(arc4random_uniform(26) + 1)]
... broken down for readability.
(Possible in future Swift version)
If the type inference weren't broken inout closure parameters (as arguments to closures), we could reduce the above to:
let powerballNumbers = Array(sequence(state: Array(1...69), next: {
$0.remove(at: Int(arc4random_uniform(UInt32($0.count)))) })
.prefix(5).sorted()) + [Int(arc4random_uniform(26) + 1)]
If we'd also allow the following extension
extension Int {
var rand: Int { return Int(arc4random_uniform(UInt32(exactly: self) ?? 0)) }
}
Then, we could go on to reduce the one-line to:
let powerballNumbers = Array(sequence(state: Array(1...69), next: { $0.remove(at: $0.count.rand) }).prefix(5).sorted()) + [26.rand + 1]
Xcode 10 • Swift 4.2
Swift now has added shuffled() to ClosedRange and random(in:) to Int which now makes this easily accomplished in one line:
func pball() -> [Int] {
return (1...69).shuffled().prefix(5).sorted() + [Int.random(in: 1...26)]
}
Further trimmings:
Because of the return type of pball(), the Int can be inferred in the random method call. Also, .prefix(5) can be replaced with [...4]. Finally, return can be omitted from the one-line function:
func pball() -> [Int] {
(1...69).shuffled()[...4].sorted() + [.random(in: 1...26)]
}

Swift returning the indexes that will sort an array (similar to numpy argsort) [duplicate]

This question already has an answer here:
Index of element in sorted()
(1 answer)
Closed 7 years ago.
I'm trying to return the indices of an array which correspond to the sorted values. For example,
let arr = [7, 10, -3]
let idxs = argsort(arr) // [2, 0, 1]
My attempt works but is not pretty, and only functions for CGFloat. I'm looking for some ways in which I can improve the function, make it generic and easier to read. The code just looks ugly,
func argsortCGFloat( a : [CGFloat] ) -> [Int] {
/* 1. Values are wrapped in (index, values) tuples */
let wrapped_array = Array(Zip2(indices(a),a))
/* 2. A comparator compares the numerical value from
two tuples and the array is sorted */
func comparator(a: (index : Int, value : CGFloat), b: (index : Int, value : CGFloat)) -> Bool {
return a.value < b.value
}
var values = sorted(wrapped_array, comparator)
/* 3. The sorted indexes are extracted from the sorted
array of tuples */
var sorted_indexes: [Int] = []
for pair in values {
sorted_indexes.append(pair.0)
}
return sorted_indexes
}
You can do it by creating an array of indexes, and sorting them using the array from the outer context, like this:
func argsort<T:Comparable>( a : [T] ) -> [Int] {
var r = Array(indices(a))
r.sort({ a[$0] > a[$1] })
return r
}
let arr = [7, 10, -3]
let idxs = argsort(arr)
println (idxs)

What is the exact definition of the for loop in Rust?

I'm coming from a C (and to a lesser extent, C++) background. I wrote the following code snippet:
fn main() {
let my_array = [1, 2, 3];
let print_me = |j| println!("= {}", j);
for k in my_array.iter() {
print_me(k);
}
}
This compiled and ran as expected, but then I specified the type of the argument passed to the closure print_me thus:
fn main() {
let my_array = [1, 2, 3];
let print_me = |j: i32| println!("= {}", j);
for k in my_array.iter() {
print_me(k);
}
}
I got a compilation error:
error[E0308]: mismatched types
--> src/main.rs:6:22
|
6 | print_me(k);
| ^
| |
| expected i32, found &{integer}
| help: consider dereferencing the borrow: `*k`
|
= note: expected type `i32`
found type `&{integer}`
Now this confused me until I changed k to &k in the for statement, which worked fine:
fn main() {
let my_array = [1, 2, 3];
let print_me = |j: i32| println!("= {}", j);
for &k in my_array.iter() {
print_me(k);
}
}
It seems that I misunderstood the for syntax itself -- or maybe the exact workings of an iterator -- or maybe the usage syntax of a reference vis-a-vis a pointer [which are related but distinct in C++].
In the construct for A in B { C1; C2; ... Cn }, what exactly are A and B supposed to be?
First of all, here's a link to the definition of for in the reference.
To summarise, B is any expression which evaluates to something that can be converted into a value that implements the Iterator<T> trait, whilst A is a irrefutable pattern that binds values of type T.
In your specific case, slice::iter returns an Iter<i32>, which implements Iterator<Item = &i32>. That is, it doesn't yield i32s, it yields &i32s.
Thus, in both the first and second examples, k is actually binding to &i32s, not i32s. When you specified the type of the closure, you were actually specifying the wrong type. The reason the final example works is because A is a pattern, not a variable name. What &k is actually doing is "de-structuring" the &i32, binding the i32 part to a variable named k.
The "irrefutable" part simply means that the pattern must always work. For example, you can't do for Some(x) in thingy where thingy implements Iterator<Option<_>>; Some(x) would not necessarily be valid for every element in the iterator; thus, it's a refutable pattern.
Many iterators actually return a reference rather than a value. To be sure, you have to check the return type of .iter(), which should be of the form Iterator<Item = X>: X will be the type of the variable returned.
So here:
fn main() {
let my_array = [1, 2, 3];
let print_me = |j: i32| println!("= {}", j);
for k in my_array.iter() {
print_me(k);
}
}
This X is &i32 (a reference to i32), and therefore k has type &i32.
This is why, when calling print_me, there is an error: &i32 is passed where i32 is expected.
There are multiple possible fixes here:
specify a different type to print_me:
let print_me = |j: &i32| println!("= {}", j);
dereference the value of k:
print_me(*k);
change the type of k by destructuring in the loop:
for &k in my_array.iter() { ... }
The destructuring occurs because for .. in accepts an irrefutable pattern, so you can pattern match like you would do in a match expression, except that the variable's type has to match (otherwise you get a compiler time error).
To better illustrate it, we can use a slightly more complicated example:
fn main() {
let my_array = [(1, 2), (2, 3), (3, 4)];
let print_me = |a: i32, b: i32| println!("= {} {}", a, b);
for &(j, k) in my_array.iter() {
print_me(j, k)
}
}
The type of my_array is [(i32, i32)]: an array of tuples of 2 i32. The result of .iter() is therefore of type Iterator<Item = &(i32, i32)>: an iterator to a reference to a tuple of 2 i32 aka &(i32, i32).
When we use the irrefutable pattern &(j, k) what happens is that we destructure the tuple so that:
the first element binds to j (inferred to be of type i32, only works because i32 is Copy)
the second element binds to k ((inferred to be of type i32)
j and k thus become temporary copies of the i32 inside this element.

Random number generate issue in swift language - EXC_BAD_INSTRUCTION

I tried to generate an array with strings in random order, but always got the error "Thread1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)" at the end of function randomPile. Below is my code:
import UIKit
class RandomView: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var cardOrder = ["HeartSix","HeartNine", "ClubQueen", "SpadeKing" ]
// cannot randomlize due to the lanuage drawbacks.
cardOrder = randomPile(cardOrder)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// random the order of the original card pile
func randomPile(arrayPile: String[]) -> String[] {
var arry = arrayPile
for( var i = arry.count-1; i > 0; --i){
var r = Int(arc4random())%(i+1)
var a = arry[r]
arry[r] = arry[i]
arry[i] = a
}
return arry
}
}
Not an answer, presented here for code formation:
This works for me both in a playground and in an app:
var cardOrder: String[] = ["HeartSix","HeartNine", "ClubQueen", "SpadeKing" ]
println(cardOrder)
cardOrder = randomPile(cardOrder)
println(cardOrder)
Perhaps the error is elsewhere.
Note: var r = Int(arc4random_uniform(UInt32(i+1))) is both simpler and avoids bias.
Also not an answer, because I can also run in playground and so I don't know where your problem is coming in. However, there's no need to create a new reference to the array and return it. I also implemented a Fisher-Yates shuffle variant which is geared towards an integer PRNG that excludes its upper bound, as arc4random_uniform does:
func randomPile(myArray: String[]) -> Void {
for i in 0..(myArray.count - 1) {
let j = Int(arc4random_uniform(UInt32(myArray.count - i))) + i
let tmp = myArray[i]
myArray[i] = myArray[j]
myArray[j] = tmp
}
}
let cardOrder: String[] = ["HeartSix","HeartNine", "ClubQueen", "SpadeKing" ]
println(cardOrder)
randomPile(cardOrder)
println(cardOrder)
After invoking this on your array, it's shuffled, no need for reassignment to cardOrder.
Addendum - I just checked, and since cardOrder doesn't appear again on the left of an assignment it can be declared with let.
You can also make the shuffle capability generic, so why not?
func shuffle<T>(myArray: T[]) -> Void {
for i in 0..(myArray.count - 1) {
let j = Int(arc4random_uniform(UInt32(myArray.count - i))) + i
let tmp:T = myArray[i]
myArray[i] = myArray[j]
myArray[j] = tmp
}
}
let cardOrder: String[] = ["HeartSix","HeartNine", "ClubQueen", "SpadeKing"]
println(cardOrder) // [HeartSix, HeartNine, ClubQueen, SpadeKing]
shuffle(cardOrder)
println(cardOrder) // sample result: [SpadeKing, HeartNine, HeartSix, ClubQueen]
let intValues = [1,2,3,4,5,6,7,8,9,10]
println(intValues) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
shuffle(intValues)
println(intValues) // sample result: [3, 10, 8, 4, 9, 7, 1, 2, 5, 6]

Resources