Cannot assign sorted array to a variable in Swift [closed] - swift

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I'm trying to sort one array and assign it to the other. Both arrays are identically defined like so:
var arrayA: [String: [Int]] = [:]
var sortedArrayA:[String: [Int]] = [:]
sortedArrayA = arrayA.sort{ $0.0 < $1.0 } // error on this line.
I am gettin this error:
Cannot assign value of type [(String, [Int])] to type [String : [Int]]
What I'm trying to achieve is to make this dictionary:
["c" : [1,2,3], "a" : [2,3,3], "b" : [4,4,4]]
sorted like this:
["a" : [2,3,3], "b" : [4,4,4], "c" : [1,2,3]]
If it makes sence.

Yeah, I know closures in Swift are cool. But they are not cool enough to infer that you want to sort an array from this code:
var arrayA: [Int] = []
var sortedArrayA:[Int] = []
sortedArrayA = arrayA{ $0 < $1 }
And your code is even worse! You didn't even declare arrays! What you declared are dictionaries which are supposed to not be sorted!
Anyway, just learn the syntax of arrays: it's a pair of square brackets surrounding the type of array you want. So an array of Ints will be [Int] and an array of Strings will be [String].
Got it? Cool.
"But I only have dictionaries, though..." you said sadly. If you only have dictionaries, you can either sort its keys or values. I think you probably need to sort the values.
let values = someDictionary.values // if you want to sort keys, use .keys instead
Now you need to actually call the sort method in order to sort. Just writing a closure is not going to work.
let sortedValues = values.sort(<)
You can do this with any arrays of course!
let array = [3, 2, 1]
let sortedArray = array.sort(<)

In your question you say that you use array but actually you are using dictionaries. And your syntax for this is wrong. you can declare empty dictionary like this: var dictionary: [String:Int] = (). But to answer your real question you can achieve it like this:
let arrayA = ["c" : [1,2,3], "a" : [2,3,3], "b" : [4,4,4]]
let sortedDict = arrayA.sort { $0.0 < $1.0 }
print("\(sortedDict)")

Try and figure out the array sorting in Playground, in swift you can just use .sort() to sort the array. For example, for array of integers:
var array = [Int]() //initial empty array
array = [2, 1, 4, 3]
array = array.sort() // array is now sorted

Related

Ordering of Dictionary Swift

I'm trying to work through a problem at the moment which is currently doing the rounds on the internet. The problem is: Given an array of characters, find the first non repeating character. I had a go at it and solved it but I was curious about how other people solved it so I did some looking around and found this answer:
let characters = ["P","Q","R","S","T","P","R","A","T","B","C","P","P","P","P","P","C","P","P","J"]
var counts: [String: Int] = [:]
for character in characters {
counts[character] = (counts[character] ?? 0) + 1
}
let nonRepeatingCharacters = characters.filter({counts[$0] == 1})
let firstNonRepeatingCharacter = nonRepeatingCharacters.first!
print(firstNonRepeatingCharacter) //"Q"
Source: Finding the first non-repeating character in a String using Swift
What I don't understand about this solution, is why it always returns Q, when there are other elements "S" "A" "B" and "J" that could be put first when the filter is applied to the dictionary. My understanding of dictionaries is that they are unordered, and when you make one they change from run to run. So if I make one:
let dictionary:[String:Int] = ["P": 9, "C": 8, "E": 1]
And then print 'dictionary', the ordering will be different. Given this, can anyone explain why the solution above works and maintains the order in which the dictionary elements were added?
You are not looking correctly at the code. The filter is not applied to a dictionary. It is applied to the array (characters), which has a defined order. The dictionary is used only to store counts.

Add Array Multiple Objects to [Any] in Swift 3 [duplicate]

This question already has answers here:
Swift 3 unable to append array of objects, which conform to a protocol, to a collection of that protocol
(2 answers)
Closed 6 years ago.
I'm trying to understand the best way to add multiple objects of different types to an [Any] array. This doesn't work in a playground in Swift 3, unless I explicitly cast the arrays and the objects in the arrays to Any.
var anyArray: [Any] = []
let strings = ["sup", "cool"]
let numbers = [5, 3]
anyArray += strings
anyArray += numbers
anyArray
It fails with the message - Cannot convert value of type '[Any]' to expected argument type 'inout _'
var arr = [Any]()
let arr1:[Any] = [2,3,4]
let arr2:[Any] = ["32","31"]
arr += arr1
arr += arr2
print(arr)
I think this is another case of useless error messages from Swift's compiler. The real issue is that AnyObject means any object (reference type); structs -- which both Int and String are -- don't count because they are value types. If you want to refer to any type at all, use Any.

Populate a multidimensional array with a loop [duplicate]

This question already has answers here:
Error: "array index out of range" in multidimensional array
(2 answers)
Closed 6 years ago.
I'm trying to populate a multidimensional array with this code:
var array = [[Int]]()
for i in 0...3 {
for j in 0...3{
array[i][j] = i + j <<- Error
}
}
But I get an error:
fatal error: Index out of range
What am I doing wrong?
[[Int]] is not a multidimensional array. It is an array of arrays. That's a very different thing. For example, in an array of arrays, each row may have a different number of columns. It's generally a bad idea to use a nested array as a multidimensional array, particularly a mutable one. It's often incredibly inefficient to modify because it causes a lot of copying every time you change it.
Swift doesn't have a multidimensional array type. If you really need one, you generally have to build it yourself, or redesign to avoid it. If it's small enough, and doesn't change much, it's not that big a deal, but don't let them get large.
That said, the problem is that element [0][0] doesn't exist because you didn't create it. You'd need to initialize the array this way before using it:
var array = Array(repeating: Array(repeating: 0, count: 4), count: 4)
This creates an array of 4 arrays of 4 zeros.
If you want specifically the layout you describe, possibly a better approach is mapping, which is likely going to be more efficient (since it doesn't keep modifying the nested array):
let array = (0...3).map { i in
(0...3).map { j in
return i + j
}
}
Calling array[i][j] is for elements that are already there. You cannot use it to initialize the array, because currently it is just an empty array. You should be using .append instead. Keep in mind that this actually isn't a multi-dimensional array like Rob Napier states, but it accomplishes the same goal in this scenario. Try something like this:
var array = [[Int]]()
for i in 0...3 {
var subArray = [Int]()
for j in 0...3 {
subArray.append(i + j)
}
array.append(subArray)
}
This prints:
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]
Again, may not be the best approach, but this is just how you could do it in Swift.

Adding Values In Dictionary With Swift

I have this Dictionary:
var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8]
and I want to add the values for example to have the result as 30 , how can I do that? In other words, how can I only add the numbers, not the words?
Since an answer has been accepted and it isn't a very good one, I'm going to have to give up on the socratic method and show a more thematic way of answering this question.
Given your dictionary:
var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8]
You get the sum by creating an array out of the dict.values and reducing them
let sum = Array(dict.values).reduce(0, +)
Or you could use the bare form of reduce which doesn't require the array to be created initially:
let sum = reduce(dict.values, 0, +)
Or the more modern version, since reduce is defined on an Array
let sum = dict.values.reduce(0, +)
The accepted answer doesn't use the power of swift
and the answer that does is outdated.
The simplest updated solution is:
let valuesSum = dict.values.reduce(0, +)
start with zero, and sum the values of all the elements
As explained in the documentations here. You access and modify a dictionary through its methods and properties, or by using subscript syntax. Read the doc.
var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8]
To access a value in your dictionary you can use the subscript syntax:
if let cola = dict["cola"] as? Int { // to read the value
// Do something
}
dict["cola"] = 30 // to change the value
dict["pepsi"] = 25 // to add a new entry to your dictionary
dict["fanta"] = nil // to delete the fanta entry.
to read all the value in your dictionary
var sum = 0
for (drinkName, drinkValue) in dict {
println("\(drinkName): \(drinkValue)")
sum += drinkValue
}
or you can
var sum = 0
for drinkValue in dict.values {
sum += drinkValue
}

Immutable Dictionary value change

Can we change any pair value in let type Dictionary in Swift Langauage.
like :
let arr2 : AnyObject[] = [1, "23", "hello"]
arr2[1] = 23
arr2 // output: [1,23,"hello"]
let arr1 :Dictionary<Int,AnyObject> = [1: "One" , 2 : 2]
arr1[2] = 4 // not posible error
arr1
In Case of Immutable Array we can change its value like above but not in case of Immutable
Dictionary. Why?
This is taken from The Swift Programming Language book:
For dictionaries, immutability also means that you cannot replace the
value for an existing key in the dictionary. An immutable dictionary’s
contents cannot be changed once they are set.
Immutability has a slightly different meaning for arrays, however. You
are still not allowed to perform any action that has the potential to
change the size of an immutable array, but you are allowed to set a
new value for an existing index in the array.
Array declared with let has only immutable length. Contents can still be changed.
Dictionary declared with let is completely immutable, you can't change contents of it. If you want, you must use var instead of let.
Swift has changed a lot since then.
Array and Dictionary are value types. When declared with let, they cannot change any more. Especially, one cannot re-assign them, or the elements in them.
But if the type of the elements is reference type, you can change the properties of the elements in Array or Dictionary.
Here is a sample.(run in Xcode6 beta-6)
class Point {
var x = 0
var y = 0
}
let valueArr: [Int] = [1, 2, 3, 4]
let refArr: [Point] = [Point(), Point()]
valueArr[0] = -1 // error
refArr[0] = Point() // error
refArr[0].x = 1
let valueDict: [Int : Int] = [1: 1, 2: 2]
let refDict: [Int: Point] = [1: Point(), 2: Point()]
valueDict[1] = -1 //error
refDict[1] = Point() //error
refDict[1]!.x = -1