Find the sum of an array in swift - swift

I have an array that holds integer values. And I have defined it like so:
#State private var numbers: Array = []
the array is updated as the user uses the app. At a certain point, I need to find the sum of all the values in the array. Here is what I tried to do:
let sumOfNum = numberz.reduce(0, +)
However, this is giving me the following error on the plus(+) symbol:
Cannot convert value of type '(Int) -> Int' to expected argument type '(Int, Any) throws -> Int'
Not sure what the problem is. Any help or guidance would be appreciated.

Your issue is probably your Array declaration. You should declare is as an array of Int instead of an array of Any.
So your array declaration should be
#State private var numbers: [Int] = []

Related

Swift 4.2: what does the following declaration mean

I am new to swift and IOS so there is a lot of unknown. What does the following declaration statement mean?
private let _digest: (UInt64, UInt64)
It's a tuple. Just like how an array has an index for an element, this variable can also be accessed using . operator followed by the index.
_digest.0
_digest.1
However, if you want to access them using using a name rather than the index, that is also possible. (You can still access it using the index)
private let _digest: (first: UInt64, second: UInt64)
_digest.first
_digest.second
For more on Tuples.
This is a private constant of type tuple, which contains two UInt64 values.
You can read about tuples and other types in Swift here
An example:
let someTuple: (Double, Double) = (3.14159, 2.71828)
Usage:
print(someTuple.0) // 3.14159
What you are basically doing is declaring a constant variable - because of the keyword let - called _digest and you are assigning the type (UInt64, UInt64) to it, which is a tuple with two variables of type UInt64.
Its a tuple that holds two UInt64.
Tuple is a group of different values represented as one . According to apple, a tuple type is a comma-separated list of zero or more types, enclosed in parentheses. It’s a miniature version of a struct.
let person = ("John", "Smith")
var firstName = person.0 // John
var lastName = person.1 // Smith
Also, if needed its possible to access there elements by name instead of index.
var person = (fName:"John", lName:"Smith", age:Int())
person.age = 33
print(person.fName) // John
print(person.lName) // Smith
print(person.age) // 33
Further, the type of a tuple is determined by the values it has. So ("tuple", 1, true) will be of type (String, Int, Bool).
For more information please visit here

Cannot use mutating member on immutable value of type [String]

I failed to append String by using following code:
(labGroups[labGroupIndex!].labs[labIndex!].tstDspGps[tstDspGpsIndex!].tests[testsIndex!]["specialReqValues"] as![String]).append("sdfsdf")
Error:
Cannot use mutating member on immutable value of type
'[String]'
And I can append value by using following code:
var arr = labGroups[labGroupIndex!].labs[labIndex!].tstDspGps[tstDspGpsIndex!].tests[testsIndex!]["specialReqValues"] as![String]
arr.append("testValue")
However, it only affect the variable arr.
That is not what I want, when I print:
((labGroups[labGroupIndex!].labs[labIndex!].tstDspGps[tstDspGpsIndex!].tests[testsIndex!]["specialReqValues"] as![String]))
it still has nil value.
Can anyone help to solve this problem?

How to assign a value to [any]

When I set c to a
var a: [Any]
var c: Array<PostCategory>
error shown:
cannot convert value of type 'Array' to expected argument type
[Any]
how to solve the problem?
The error message is a bit misleading but try initializing the array before assigning it:
var c: Array<PostCategory> = []
...or...
var c = Array<PostCategory>()
I bet your PostCategory is a struct. Apparently struct arrays aren't convertible to an Any array. This is weird because all types conforms to the Any protocol.
If you change the PostCategory to a class instead, it should work fine. You might need to create a new initializer for the class though, since classes doesn't give you the same default initializer as a struct does.

Difference between [] and []() in Swift

I tried searching around for what this is
[]()
But I'm not really sure. In a playground, I did this:
var test = [Int]();
test.append(1);
test.append(2);
If I leave off the () and do
var test = [Int];
test.append(1);
test.append(2);
It still looks like an array of Ints to me. What is the difference?
Type() means "call init()" - i.e., make a new instance of Type.
[Int] is a type, like String. [Int] means "array-of-Int".
String() makes a new empty String instance. [Int]() makes a new empty array-of-Int instance.
You can declare a variable as being of type array-of-Int. Or you can make and assign a new array-of-Int instance. Which is what you are doing here:
var test = [Int]()
But you cannot assign a type to a variable without further syntax. Thus, this is illegal:
var test = [Int]
EXTRA for experts
You can say:
var test = [Int].self
That does assign the type to the variable! That is unlikely to be what you want here, because now you have no array; you have a type, itself, as object!!
[Type] is syntactic sugar for Array<Type>, so it represents the array type, which is a generic struct, and for which you specify the type of elements it holds (Int in this example)
So the difference between:
[Int]
and
[Int]()
is the same as for
Array<Int>
and
Array<Int>()
The first is just a type, which you can use when declaring a variable or a function parameter.
The second invokes the parameterless constructor on that type, i.e. creates an instance of that type.

Can you append to an array inside a dict?

In Swift, you can declare a dict where the value is an array type, eg:
var dict: [Int: [Int]] = [:]
However, if you assign an array for a given key:
dict[1] = []
then it appears that Swift treats the array as immutable. For example, if we try:
(dict[1] as [Int]).append(0) // explicit cast to avoid DictionaryIndex
then we get the error 'immutable value of type [Int] has only mutating members named 'append''.
If we explicitly make the array mutable, then the append works, but doesn't modify the original array:
var arr = dict[1]!
arr.append(0) // OK, but dict[1] is unmodified
How can you append to an array which is a dict value?
More generally, how can you treat the values of a dictionary as mutable?
One workaround is to reassign the value afterwards, but this does not seem like good practice at all:
var arr = dict[1]!
arr.append(0)
dict[1] = arr
Try unwrapping the array instead of casting:
dict[1]!.append(0)