Is there an intrinsic size limit for the static initializer in Swift? - swift

In a class I have class variables, simulated by a struct with static members like this:
internal class DEAccountCheck : AccountCheck {
private struct Static {
static var methodParameters: [String: (UInt16, [UInt16])] = [ // Modulus + weights indexed by method id.
"00": (10, [2, 1, 2, 1, 2, 1, 2, 1, 2]),
"01": (10, [3, 7, 1, 3, 7, 1, 3, 7, 1]),
"02": (11, [2, 3, 4, 5, 6, 7, 8, 9, 2]),
"03": (10, [2, 1, 2, 1, 2, 1, 2, 1, 2]),
...
]
}
There are more than 200 lines (entries) for the methodParameter dictionary. If I run my app I get an EXC_BAD_INSTRUCTION exception with the debugger stopping in the middle of my static initializer. I checked thereon when this starts to happen and found that I can have up to 172 values. One more and: puff.
As I can successfully add all entries by normal code the question arises if there's some known limit for static intializers.

It turned out that the exception came from a duplicate key, which is not allowed. If the error messages in Swift would be more user friendly that problem would have been seen much easier. ATM error messages in Swift are simply terrible.

Related

Why isn't there a formSubtracting() method in Swift for Sets

In Swift there is a Form... equivalent for the Sets methods intersection(), symmetricDifference() and union(), i.e. formIntersection(), formSymmetricDifference() and formUnion().
But for the method subtracting() there is no method called formSubtracting. Does anyone know why this is so, because it seams I now have to use something like mySet = mySet.subtracting(anotherSet)
subtract(_:) is what you are looking for:
Removes the elements of the given set from this set.
Example:
var mySet: Set = [1, 2, 3, 4, 5]
let anotherSet : Set = [2, 4, 6, 8]
mySet.subtract(anotherSet)
print(mySet) // [3, 1, 5]
There is also a variant which takes another sequence (of the same element type) as the argument, e.g. an array:
var mySet: Set = [1, 2, 3, 4, 5]
let anotherSequence = [2, 4, 6, 8]
mySet.subtract(anotherSequence)
print(mySet) // [3, 1, 5]

Can you merge two Flux, without blocking, such that the result only contains unique elements?

Is there a way to merge two Flux such that the result only contains unique elements? I can block on the output and then convert it to a set, but is there a way that does not depend on blocking?
Source (Kotlin)
val set1 = Flux.just(1, 2, 3, 4, 5)
val set2 = Flux.just(2, 4, 6, 8, 10)
val mergedSet = set1.mergeWith(set2)
println(mergedSet.collectList().block())
Output
[1, 2, 3, 4, 5, 2, 4, 6, 8, 10]
Desired Output (order is not important)
[1, 2, 3, 4, 5, 6, 8, 10]
You can use the Flux's merge method and then apply distinct() to it.
Flux.merge (Flux.just(1, 2, 3, 4, 5), Flux.just(2, 4, 6, 8, 10)).distinct();
This way you get a flux which produces only distinct values.

Do you have any idea or documentation about why we have arc4random_stir() in swift?

I have written the program below for generating random unique numbers for several number of times by invoking the function, but it seems like I'm getting the same pattern with minimal changes.
func generateRandom(withinNumber: Int) {
var i:Int = 0
var elements = Set<Int>()
while i != withinNumber {
let num:Int = Int(arc4random())%withinNumber + 1
if elements.count <= withinNumber && elements.contains(num) == false {
elements.insert(num)
}
else {
i = i-1
}
i=i+1
}
print(elements)
elements.removeAll()
}
generateRandom(withinNumber: 10)
How does I make my program effectively run to generate several random unique numbers.
Please let me know it would be very helpful for me.
You are storing your numbers in a Set and sets are not ordered, so the order the elements are shown by print is unrelated to the order in which they were added to the set.
Rather the elements of a set are stored in some manner which enables fast checking for .contains(), and this is one reason you seeing similar sequences.
If you wish to preserve order of insertion use a collection which does this, i.e. an array. Changing to an array in your code produced the following results from 9 calls:
[8, 9, 7, 10, 5, 6, 2, 3, 1, 4]
[4, 9, 10, 3, 6, 2, 1, 7, 8, 5]
[8, 3, 5, 1, 6, 4, 9, 10, 7, 2]
[5, 7, 2, 9, 8, 1, 6, 10, 3, 4]
[2, 3, 7, 6, 9, 1, 8, 10, 5, 4]
[9, 10, 2, 4, 6, 8, 5, 7, 1, 3]
[9, 10, 2, 5, 4, 7, 3, 8, 1, 6]
[1, 6, 4, 5, 8, 2, 3, 9, 7, 10]
[6, 10, 5, 3, 2, 8, 1, 9, 7, 4]
You are also generating 10 random numbers in the range 1 to 10 and avoiding duplicates, so the results is always going to be the numbers 1 to 10 in some order.
To generate a random number in a given range do not use %, instead use the provided arc4random_uniform() which will give better a better distribution.
The function mention in your title arc4random_stir() is available in Swift.
BTW (somewhat opinion based): It is better to write !e (! being the boolean not operator) rather than e == false, and never ever write e == true which is the long form of e!
BTW (SO etiquette): Don't link to your code (or paste in images of it). Reduce to a small example which demonstrates the issue (not required in your case) and insert directly in the question. Keep tags minimal and appropriate. These edits were done for you this time by myself and others, you will know for next time.
HTH

How do I detect Change in Observable?

Say I have IObservable and I want an observable that ignores the repeating numbers of the original one, how can I do that ? I tried the following
I have tried GroupBy() but it is a hot observable, which is not going to work. And all I need to compare with is with the previous one.
You want to use DistinctUntilChanged.
// yields 1, 4, 4, 2, 2, 2, 3, 4, 4, 3
IObservable<int> a = ...;
// yields 1, 4, 2, 3, 4, 3
IObservable<int> b = obs.DistinctUntilChanged();

How to concatenate a range of ranges ("RoR") in D?

What is the best way to lazily concatentate together a range of ranges in D?
Use std.algorithm.joiner. e.g.
auto ror = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ];
auto joined = joiner(ror);
assert(equal(joined, [1, 2, 3, 4, 5, 6, 7, 8, 9]));
Try chain:
http://dlang.org/phobos/std_range.html#chain