Are there any side effects of exiting a loop with return rather than break in Swift? - swift

I need to match items in two different arrays (one with imported items and another with local items that share some properties with the imported items) to sync two databases that are quite different. I need to use several criteria to do the matching to increase the robustness of finding the right local item and match it with the imported item. I could check each criterium in the same loop, but that is too expensive, because the criteria are checked by the likelihood of success in descending order. Thus, in my first implementation I used a boolean flag called found to flag that the checking of other criteria should be ignored.
Using pseudo code:
// calling code for the matching
for item in importedItems {
item.match() }
In the imported item class:
match()
{
var found = false
for localItem in localItems
{
if (self.property == localItem.property)
{
// update the local item here
found = true
break
}
}
// match with less likely 2nd property
if (!found)
{
for localItem in localItems
{
if (self.property2 == localItem.property2)
{
// update the local item here
found = true
break
}
}
}
The if !found {...} pattern is repeated two additional times with even less likely criteria.
After reviewing this code, it is clear that this can be optimized by returning instead of breaking when there is a match.
So, my question is "are there any known side-effects of leaving a loop early by using return instead of break in Swift?" I could not find any definitive answer here in SO or in the Swift documentation or in blogs that discuss Swift flow control.

No, there are no side effects, quite the opposite it's more efficient.
It's like Short-circuit evaluation in a boolean expression.
But your code is a bad example because found cannot be used outside the function.
This is a more practical example returning a boolean value
func match() -> Bool
{
for localItem in localItems
{
if (self.property == localItem.property)
{
// update the local item here
return true
}
}
....
return false
}

If you know for sure that you can return because nothing else have to be done after the loop then there are no side effects of using return

Related

How to write to an Element in a Set?

With arrays you can use a subscript to access Array Elements directly. You can read or write to them. With Sets I am not sure of a way to write its Elements.
For example, if I access a set element matching a condition I'm only able to read the element. It is passed by copy and I can't therefore write to the original.
For example:
columns.first(
where: {
$0.header.last == Character(String(i))
}
)?.cells.append(value: addValue)
// ERROR: Cannot use mutating member on immutable value: function call returns immutable value
You can't just change things inside a set, because of how a (hash) set works. Changing them would possibly change their hash value, making the set into an invalid state.
Therefore, you would have to take the thing you want to change out of the set, change it, then put it back.
if var thing = columns.first(
where: {
$0.header.last == Character(String(i))
}) {
columns.remove(thing)
thing.cells.append(value: addValue)
columns.insert(thing)
}
If the == operator on Column doesn't care about cells (i.e. adding cells to a column doesn't suddenly make two originally equal columns unequal and vice versa), then you could use update instead:
if var thing = columns.first(
where: {
$0.header.last == Character(String(i))
}) {
thing.cells.append(value: addValue)
columns.update(thing)
}
As you can see, it's quite a lot of work, so maybe sets aren't a suitable data structure to use in this situation. Have you considered using an array instead? :)
private var _columns: [Column]
public var columns : [Column] {
get { _columns }
set { _columns = Array(Set(newValue)) }
// or any other way to remove duplicate as described here: https://stackoverflow.com/questions/25738817/removing-duplicate-elements-from-an-array-in-swift
}
You are getting the error because columns might be a set of struct. So columns.first will give you an immutable value. If you were to use a class, you will get a mutable result from columns.first and your code will work as expected.
Otherwise, you will have to do as explained by #Sweeper in his answer.

How to implement non chronological backtracking

I'm working on a CDCL SAT-Solver. I don't know how to implement non-chronological backtracking. Is this even possible with recursion or is it only possible in a iterative approach.
Actually what i have done jet is implemented a DPLL Solver which works with recursion. The great differnece from DPLL and CDCL ist that the backracking in the tree is not chronological. Is it even possible to implement something like this with recursion. In my opionion i have two choices in the node of the binary-decision-tree if one of to path leads i a conlict:
I try the other path -> but then it would be the same like the DPLL, means a chronological backtracking
I return: But then i will never come back to this node.
So am i missing here something. Could it be that the only option is to implement it iterativly?
Non-chronological backtracking (or backjumping as it is usually called) can be implemented in solvers that use recursion for the variable assignments. In languages that support non-local gotos, you would typically use that method. For example in the C language you would use setjmp() to record a point in the stack and longjmp() to backjump to that point. C# has try-catch blocks, Lispy languages might have catch-throw, and so on.
If the language doesn't support non-local goto, then you can implement a substitute in your code. Instead of dpll() returning FALSE, have it return a tuple containing FALSE and the number of levels that need to be backtracked. Upstream callers decrement the counter in the tuple and return it until zero is returned.
You can modify this to get backjumping.
private Assignment recursiveBackJumpingSearch(CSP csp, Assignment assignment) {
Assignment result = null;
if (assignment.isComplete(csp.getVariables())) {
result = assignment;
}
else {
Variable var= selectUnassignedVariable(assignment, csp);
for (Object value : orderDomainValues(var, assignment, csp)) {
assignment.setAssignment(var, value);
fireStateChanged(assignment, csp);
if (assignment.isConsistent(csp.getConstraints(var))) {
result=recursiveBackJumpingSearch(csp, assignment);
if (result != null) {
break;
}
if (result == null)
numberOfBacktrack++;
}
assignment.removeAssignment(var);
}
}
return result;
}

Anybody who can help understand this Knockout Observable?

I am a complete beginner in Software Development, and got introduced to a project which I have a hard time understanding and knowing where to start
this.isConfirmationCar = ko.computed(() => {
if (this.selectedTemplate() && this.selectedTemplate().Id ===
<number>Enums.PolicyEmailTemplates.ConfirmationOfCoverCar) {
return true;
} else {
return false;
}
});
It looks to be returning a boolean value and storing it within this.isConfirmationCar.
This being either true/false dependant on the argument defined as -
{ if (this.selectedTemplate() && this.selectedTemplate().Id === Enums.PolicyEmailTemplates.ConfirmationOfCoverCar) { return true; } else { return false; }
FYI - Knockoutjs has a great website with an excellent tutorial http://learn.knockoutjs.com/#/?tutorial=intro
It covers the ko.computed function in the intro worth a look!
What you have there is a computed observable which is nothing more but a function which inside of its body tracks ANY other observable used. Not only it tracks it but it would execute itself again and again on those tracked observables values mutating.
Computed observables are extremely useful. Note that they have various "options" in terms of how to defined them and some interesting siblings like the pureComputed observables.
In this example the computed isConfirmationCar is used to track the values of the other observables selectedTemplate and selectedTemplate. The moment any of those change that computed with refresh its value which is why it is used in this context for tracking isConfirmationCar.
Hope this helps.

Break out of double foreach in Scala

I have to return true or false based on field value in inner set item. My loops is as follow
myChoice.category.foreach(category => {
category.flavours.foreach(flavour=> {
if (flavour.available) true
})
})
false
It shoudld break and return true as soon as I have true on available but its returning false all the time. Any suggestion?
I don't have your dataset to work with, but perhaps this might do it.
myChoice.category.exists(_.flavours.exists(_.available))
Scala doesn't have continue or break. Because it is a fully functional language, every expression (including a loop) must have a value. Moreover, it tries to break out of the imperative style of initializing variables and mutating them over the course of a loop. Instead, scala encourages you to use a functional style, i.e. use methods that apply to data structures as a whole to transform/search for the desired result.
For your case, you're clearly looking to see if any of the flavors have their available field set to true. Thus you could flatMap the whole nested collection to a List of Boolean, and take the or of the whole collection:
val anyAvaliable = myChoice.category.flatMap(a => a.flavours).reduce( (flavour1,flavour2) => flavour1.available || flavour2.available)
jwvh's solution is even more concise. There are many ways of accomplishing essentially the same thing. Don't fight the language, have it fight for you!
Disclaimer: the below solution is provided for completeness, but jwvh's answer should be preferred for this case and generally speaking there are better alternatives. In particular, note that return from inside a lambda is implemented using exceptions, so 1) it may perform much worse than normal method calls; 2) if you are careless you can accidentally catch it.
If this is the last thing you need to do in the method, you can just use return:
myChoice.category.foreach(category => {
category.flavours.foreach(flavour=> {
if (flavour.available) return true
})
})
false
If it isn't, you can extract a method (including a local one):
def foo = {
...
val myChoice = ...
def hasAvailableFlavorsMethod() = {
myChoice.category.foreach(category => {
category.flavours.foreach(flavour=> {
if (flavour.available) return true
})
})
false
}
val hasAvailableFlavors = hasAvailableFlavorsMethod()
...
}

How can I chain promises in Swift inside a loop?

I'm building a Swift-based iOS application that uses PromiseKit to handle promises (although I'm open to switching promise library if it makes my problem easier to solve). There's a section of code designed to handle questions about overwriting files.
I have code that looks approximately like this:
let fileList = [list, of, files, could, be, any, length, ...]
for file in fileList {
if(fileAlreadyExists) {
let overwrite = Promise<Bool> { fulfill, reject in
let alert = UIAlertController(message: "Overwrite the file?")
alert.addAction(UIAlertAction(title: "Yes", handler: { action in
fulfill(true)
}
alert.addAction(UIAlertAction(title: "No", handler: { action in
fulfill(false)
}
} else {
fulfill(true)
}
}
overwrite.then { result -> Promise<Void> in
Promise<Void> { fulfill, reject in
if(result) {
// Overwrite the file
} else {
// Don't overwrite the file
}
}
}
However, this doesn't have the desired effect; the for loop "completes" as quickly as it takes to iterate over the list, which means that UIAlertController gets confused as it tries to overlay one question on another. What I want is for the promises to chain, so that only once the user has selected "Yes" or "No" (and the subsequent "overwrite" or "don't overwrite" code has executed) does the next iteration of the for loop happen. Essentially, I want the whole sequence to be sequential.
How can I chain these promises, considering the array is of indeterminate length? I feel as if I'm missing something obvious.
Edit: one of the answers below suggests recursion. That sounds reasonable, although I'm not sure about the implications for Swift's stack (this is inside an iOS app) if the list grows long. Ideal would be if there was a construct to do this more naturally by chaining onto the promise.
One approach: create a function that takes a list of the objects remaining. Use that as the callback in the then. In pseudocode:
function promptOverwrite(objects) {
if (objects is empty)
return
let overwrite = [...] // same as your code
overwrite.then {
do positive or negative action
// Recur on the rest of the objects
promptOverwrite(objects[1:])
}
}
Now, we might also be interested in doing this without recursion, just to avoid blowing the call stack if we have tens of thousands of promises. (Suppose that the promises don't require user interaction, and that they all resolve on the order of a few milliseconds, so that the scenario is realistic).
Note first that the callback—in the then—happens in the context of a closure, so it can't interact with any of the outer control flow, as expected. If we don't want to use recursion, we'll likely have to take advantage of some other native features.
The reason you're using promises in the first place, presumably, is that you (wisely) don't want to block the main thread. Consider, then, spinning off a second thread whose sole purpose is to orchestrate these promises. If your library allows to explicitly wait for a promise, just do something like
function promptOverwrite(objects) {
spawn an NSThread with target _promptOverwriteInternal(objects)
}
function _promptOverwriteInternal(objects) {
for obj in objects {
let overwrite = [...] // same as your code
overwrite.then(...) // same as your code
overwrite.awaitCompletion()
}
}
If your promises library doesn't let you do this, you could work around it by using a lock:
function _promptOverwriteInternal(objects) {
semaphore = createSemaphore(0)
for obj in objects {
let overwrite = [...] // same as your code
overwrite.then(...) // same as your code
overwrite.always {
semaphore.release(1)
}
semaphore.acquire(1) // wait for completion
}
}