Swift 3 - distinguishing between "for loops" - for-loop

I am trying to figure out the difference between the following:
for i in A {
and
for i in 0..<A.count {
Don't they both just iterate through the array?

Swift has only one for loop, unlike some other languages. Swift's for loop iterates over a Sequence and provides (in the loop variable, i in your case) each element of that sequence.
In your first example, the sequence is A, the array itself, which means that i is an element of the array:
var A = [ "Mal", "Wash", "Kaylee" ]
for i in A {
print(i) // prints "Mal" on the first pass, then "Wash", then "Kaylee"
}
In your second example, the sequence is a Range of integers, starting at zero and ending at one less than the size of the array. So i is an integer:
for i in 0..<A.count {
print(i) // prints "0", then "1", then "2"
}
If you're using the second style and you need the array element, you need to explicitly fetch it from the array in the loop body:
for i in 0..<A.count {
print(A[i]) // prints "Mal", then "Wash", then "Kaylee"
}
This can be useful for situations where you care at least as much about indices as content:
for i in 0..<A.count {
if A[i] == "Wash" {
A.insert("Zoe", at: i + 1)
}
}
Although, if you need both the elements and indices in a sequence, the preferred Swift style is to use enumerated() instead — this provides a sequence of tuples, giving you both:
for (index, element) in A.enumerated() {
print(index, element) // prints "0 Mal", "1 Wash", "2 Kaylee"
}

Related

Answering the Longest Substring Without Repeating Characters in Kotlin

I've spend some time working on the problem and got this close
fun lengthOfLongestSubstring(s: String): Int {
var set = HashSet<Char>()
var initalChar = 0
var count = 0
s.forEach {r ->
while(!set.add(s[r]))
set.remove(s[r])
initalChar++
set.add(s[r])
count = maxOf(count, r - initialChar + 1)
}
return count
}
I understand that a HashSet is needed to answer the question since it doesn't allow for repeating characters but I keep getting a type mismatch error. I'm not above being wrong. Any assistance will be appreciated.
Your misunderstanding is that r represents a character in the string, not an index of the string, so saying s[r] doesn't make sense. You just mean r.
But you are also using r on its own, so you should be using forEachIndexed, which lets you access both the element of the sequence and the index of that element:
s.forEach { i, r ->
while(!set.add(r))
set.remove(r)
initialChar++
set.add(r)
count = maxOf(count, i - initialChar + 1)
}
Though there are still some parts of your code that doesn't quite make sense.
while(!set.add(r)) set.remove(r) is functionally the same as set.add(r). If add returns false, that means the element is already in the set, you remove it and the next iteration of the loop adds the element back into the set. If add returns true, that means the set didn't have the element and it was successfully added, so in any case, the result is you add r to the set.
And then you do set.add(r) again two lines later for some reason?
Anyway, here is a brute-force solution that you can use as a starting point to optimise:
fun lengthOfLongestSubstring(s: String): Int {
val set = mutableSetOf<Char>()
var currentMax = 0
// for each substring starting at index i...
for (i in s.indices) {
// update the current max from the previous iterations...
currentMax = maxOf(currentMax, set.size)
// clear the set to record a new substring
set.clear()
// loop through the characters in this substring
for (j in i..s.lastIndex) {
if (!set.add(s[j])) { // if the letter already exists
break // go to the next iteration of the outer for loop
}
}
}
return maxOf(currentMax, set.size)
}

How does lazyness of the slice index affects the slicing of an array/list? [RAKU]

When we slice an array with an index that exceeds the boundaries of the array we get as the result the undefined (Any)
When we pass the same slice index as a lazy list then we get as result the existing values of the array/list (and NOT any more than that):
my #a = ^5;
say #a[^10]; # (0 1 2 3 4 (Any) (Any) (Any) (Any) (Any))
say #a[lazy ^10]; # (0 1 2 3 4)
It is clear that lazyness of the slice index affects the result.
Trying to undestand the way things are and as a proof of concept I programmed my simple version of the slice mechanism:
my #a = ^5;
my #s1 = ^10;
my #s2 = lazy ^10;
sub postcircumfix:<-[ ]-> (#container, #index) {
my $iter = #index.iterator;
gather {
loop {
my $item := $iter.pull-one;
if $item =:= IterationEnd {
last;
}
with #container[$item] {
take #container[$item]
} else {
#index.is-lazy ?? { last } !! take #container[$item];
}
}
}
}
say #a-[#s1]-; # (0 1 2 3 4 (Any) (Any) (Any) (Any) (Any))
say #a-[#s2]-; # (0 1 2 3 4)
But I am wondering if my naive algorithm depicts the way that things are computed under the hood !
The source for how things are done under the hood can be found in array_slice.pm6.
Specifically, you can see the following at L73:
if is-pos-lazy {
# With lazy indices, we truncate at the first one that fails to exists.
my \rest-seq = Seq.new(pos-iter).flatmap: -> Int() $i {
nqp::unless(
$eagerize($i),
last,
$i
)
};
my \todo := nqp::create(List::Reifier);
nqp::bindattr(todo, List::Reifier, '$!reified', eager-indices);
nqp::bindattr(todo, List::Reifier, '$!current-iter', rest-seq.iterator);
nqp::bindattr(todo, List::Reifier, '$!reification-target', eager-indices);
nqp::bindattr(pos-list, List, '$!todo', todo);
}
else {
pos-iter.push-all: target;
}
So, as you've surmised, it does indeed stop after a list item doesn't exist. This is no doubt becaue many lazy lists are infinite, and iterators don't provide a way to know if they are infinite or not (the generator may be non-determinative).
If you really want to enable such a thing, you could, for instance, write your own slicer that handles lazy lists where an element may not be available, but you have to take care to ensure that things are only eagerly evaluated if you know they're finite:
multi sub postcircumfix:<-[ ]-> (#a, #b) {
lazy gather {
take #a[$_] for #b;
}
}
my #a = ^5;
my #b = lazy gather { 
for ^10 -> $i { 
# So we can track when elements are evaluated
say "Generated \#b[$i]";
take $i;
}
};
say "Are we lazy? ", #a-[#b]-;
say "Let's get eager: ", #a-[#b]-.eager;
say "Going beyond indices: ", #a-[#b]-[11]
The output of this is
Are we lazy? (...)
Generated #b[0]
Generated #b[1]
Generated #b[2]
Generated #b[3]
Generated #b[4]
Generated #b[5]
Generated #b[6]
Generated #b[7]
Generated #b[8]
Generated #b[9]
Let's get eager: (0 1 2 3 4 (Any) (Any) (Any) (Any) (Any))
Going beyond indices: Nil

Can I use 'where' inside a for-loop in swift?

Is there also a possibility to use the 'where' keyword in another place then a switch? Can I use it in a for in loop for example?
I have an array with bools, all with a value, can I do something like this:
var boolArray: [Bool] = []
//(...) set values and do stuff
for value where value == true in boolArray {
doSomething()
}
This would be a lot nicer than use an if, so I am wondering if there is a possibility to use where in combination with a for-loop. Ty for your time.
In Swift 2, new where syntax was added:
for value in boolArray where value == true {
...
}
In Pre 2.0 one solution would be to call .filter on the array before you iterate it:
for value in boolArray.filter({ $0 == true }) {
doSomething()
}
A normal for-loop will iterate all elements present in the list. But sometimes we want to iterate only when data satisfy some condition, there we can use where clause with for -loop. It's just a replacement of if condition inside the loop.
For example:
let numbers = [1,2,3,4,5,6,7]
for data in numbers {
if (data % 2 == 0) {
print(data)
}
}
can be rewritten in the simpler way as:
for data in numbers where data % 2 == 0 {
print(data)
}
Yes, you can use "where" clause with for loop.
let arr = [1,2,3,4,5]
for value in arr where value != 0 {
print(value)
}
Considering your example,
var boolArray: [Bool] = []
//(...) set values and do stuff
for value in boolArray where value == true {
doSomething()
}

Can something like map!(&:strip) be written?

I am trying to remove white space of array elements, but at the same time I want this to be inline replacement. Is something like this can be done..
lines[3..lines.length-4].map!(&:strip).delete_if { |table_name| table_name == "" }
It does not work because lines[3..lines.length-4] returns a new array, not a partial "reference" to the old one (so your map! is then just modifying in-place this new array).
An idea:
(3..lines.length-4).each { |idx| lines[idx].strip! }
When you call map! on lines[3..lines.length-4] this method is called not on your original array but on a new one, that contains slice of the original lines array. If what you need is to replace part of your lines array with its stripped and filtered elements you can do it like that:
lines[3..lines.length-4] = lines[3..lines.length-4].map(&:strip).reject { |tn| tn == "" }
Here you explicitly override slice of lines array after striping and filtering elements it contains.

Handling unions, subsets and supersets in Scala

I need to write a code snippet that would compare multiple arrays and produce the set that match the data in those arrays, produce the data set only in array A, but not in array B,C,D,in array B but not in A,C,D, being able to handle any number of arrays (i.e. dynamically looped). The code should utilize anonymous functions in Scala (i.e. not like a regular array looping like in Java).
Sounds like homework to me. By far the easiest way to do this is to throw the contents of array A into a Set and use the remove operation. This would be O(n) where n = \sum { |A|, |B|, |C|, ... }. The following solution works for arbitrary Iterable, not just Array:
def compareArrays[A](arrs: List[Iterable[A]]) = arrs match {
case a :: tail => {
val set = a.foldLeft(Set[A]()) { _ + _ }
tail.foldLeft(set) { _ -- _ }
}
case Nil => Nil
}

Resources