Why Array's :+ does not work inside for comprehension? - arrays

val tagsArray = tags.split(",")
var trimmedTagsArray: Array[String] = Array()
for(tag <- tagsArray) {
trimmedTagsArray :+ tag.trim
}
trimmedTagsArray is empty afterwards, even though tagsArray contains elements, and even if I omit the trim call.
What am I missing here?

You need to understand the :+ operator. Rather than modifying the existing trimmedTagsArray variable, the :+ is actually returning a new array with the result of the expression "tag.trim" appended to the end. Since you neither yield this result back, or assign it anywhere, this value is discarded.
I believe what you are actually looking for is to replace the line in your for comprehension with the following.
trimmedTagArray = trimmedTagArray :+ tag.trim
While this will accomplish what you want, however, it is not the best solution by far. Instead, try the following...
val trimmedTagsArray = for(tag <- tagsArray) yield {
tag.trim
}
The above will create a val (preferred in Scala over var) that has the desired values while avoiding mutable state.

It works. Just that for(...) {} returns Unit. You want :
for(tag <- tagsArray) yield {
trimmedTagsArray :+ tag.trim
}

Related

How to use an array of functions in Swift

I have read all the posts I can find here about arrays of functions - great you can do it. I figured. But none of the posts show practically how to use them (at least not what I'm trying to do). Here's what I want - they can all take the same args, but that's not a requirement.
This article is close, and will allow me to loop through to execute each function (which meets the first goal).
https://stackoverflow.com/a/24447484/11114752
But... what if I want to execute a single function by reference?
In other words, how to call just the referenced Arity2 function - for example:
// None of these work (with or without the parameter labels)
funcs.Arity2(n: 2, S: "Fred) // value of type [MyFuncs] has no member .Arity2
funcs[Arity2](n: 2, S: "Fred") // no exact matches to call in subscript
funcs[.Arity2](n: 2, S: "Fred") // Cannot call value of non-function type...
let fn = funcs.first(where: { a whole ton of permutations here to try to match Arity2 }) -- a whole lotta frustrating nope...
Help, please! Nothing I've tried works. The pre-compiler just goes in circles making suggestions that don't pan out and it will not compile.
EDIT:
The reason for the array in the first place is that I'm going to have a quite a few functions, and I don't know what they all are in advance. Essentially, I want a plugin type of architecture. Where I can add to the list of functions (ideally within an extension of the class, but that's another problem..) and not change the processing loop that executes each function in order.
I assume you need something like
_ = funcs.first {
if case let MyFuncs.Arity2(f) = $0 {
f(2, "Fred")
return true
}
return false
}
It can be achieved in a much simpler way if you know the position of the function in the array.
Assuming you have:
func someFunc(n: Int, s: String) {
print("call \(n) \(s)")
}
var funcs = [MyFuncs.Arity2(someFunc)]
you can do:
if case .Arity2(let f) = funcs.first {
f(2, "Fred")
}
By replacing funcs.first with funcs[i] you can access the i-th index (first make sure it does exist).

No var or breakable: How to "break" when a predicate is met, in an array traversal?

How would I write this programming logic into a functional method signature? I am attempting to loop/traverse an array until a condition is met, then break upon that condition. I'm mostly trying my best to avoid var and breakable from scala.util.control.Breaks. It makes use of a closure, in this case, dictionary, to check if a condition/predicate is met. The idea is that I am looping through an array until the predicate is met. I'm also avoiding converting my array to list. Would use of an array not allow me to splice the array, for example, to do pattern matching?
val dictionary = Array.fill(128)(false)
def isUnique(array: Array[Char]): Option[Char] = {
// traverse each element of the array {
// if a character.toInt is in the dictionary, insert into dictionary
// exit loop, with the character which broke the loop
// else
// set dictionary(character.toInt) to true and continue looping
// }
}
Here's an example use case:
val word = "abcdefggghijklmnopqrstuvqxyz".toArray
val charThatBrokeIt = isUnique(word)
Edit: Feel free to suggest or propose other return types as well, such as a Boolean, Tuple, Case Class, or any others. Option[Char] might not be a good resultant value on my part. For example. I may have returned false in the case that loop broke out early (short-circuited) or not.
First, a String already acts like a collection, so you should just use String instead of Array[Char]. Second, you can take advantage of laziness to allow short-circuiting while still splitting the algorithm into parts, using .view.
def breaksUnique(word: String): Option[Char] = {
val cumulativeSets = word.view.scanLeft(Set.empty[Char]){_ + _}
val zipped = cumulativeSets zip word
val nonDupsDropped = zipped dropWhile {case (set, char) => !(set contains char)}
nonDupsDropped.map{_._2}.headOption
}
The first two lines are written as if they process the entire word, but because they operate on a view, they are only calculated as needed.
cumulativeSets is a sequence of sets of every character that has been seen up to that point. If you ran it on "abb", you would get Set(), Set(a), Set(a,b), Set(a,b). That is combined with the original word using zip, giving (Set(),a), (Set(a),b), (Set(a,b),b). We then just have to drop all the pairs where the character doesn't appear in the set, then return the first element that wasn't dropped.
Early breakout always suggests recursion.
def isUnique(array: Array[Char]): Option[Char] = {
def getDup(index: Int, acc: Set[Char]): Option[Char] =
if (array.isDefinedAt(index))
if (acc(array(index))) Some(array(index))
else getDup(index+1, acc + array(index))
else None
getDup(0, Set.empty[Char])
}
Usage:
val word = "abcdefggghijklmnopqrstuvqxyz".toArray
val charThatBrokeIt = isUnique(word)
//charThatBrokeIt: Option[Char] = Some(g)

Scala sum of the arrays contained in an array

I have defined a function that receives an array of arrays. I want to get the sum of all arrays. My question is how to make that sum.
def suma[T](args: WrappedArray[T]*)(implicit n: Numeric[T]) = {
args.transpose.map(_.sum)
}
def sum[T](arr: WrappedArray[WrappedArray[T]])(implicit n: Numeric[T]) = {
val result = suma( ______ )
}
I thought I use the defined "sum" , but not how to pass the contents of the container array. Like there is a much simpler way to do this. Any ideas?
To get "sum of all arrays" you want .flatten, not .transpose.
args.flatten.sum should do it.
Or are you asking how to call a function with vargargs? For that, you need a splat operator:
val result = suma(arr:_*)

Swift: optional array count

In Objective-C, if I had the following property:
#property (strong, nonatomic) NSArray * myArray;
A method to return a number of objects in myArray would look like:
- (NSInteger) numberOfObjectsInMyArray
{
return [self.myArray count];
}
This would return either the number of objects in the array, or 0 if myArray == nil;
The best equivalent I can think of for doing this in Swift is:
var myArray: Array<String>?
func numberOfObjectsInMyArray() -> Int
{
return myArray ? myArray!.count : 0
}
So checking the optional array contains a value, and if so unwrap the array and return that value, otherwise return 0.
Is this the correct way to do this? Or is there something simpler?
Try using the nil coalescing operator.
According to the Apple Documentation:
The nil coalescing operator (a ?? b) unwraps an optional a if it contains a value, or returns a default value b if a is nil.
So your function could look like this:
func numberOfObjectsInMyArray() -> Int {
return (myArray?.count ?? 0)
}
I agree with others that this could be a bad idea for a number of reasons (like making it look like there is an array with a count of "0" when there isn't actually an array at all) but hey, even bad ideas need an implementation.
EDIT:
So I'm adding this because two minutes after I posted this answer, I came across a reason for doing exactly what the author wants to do.
I am implementing the NSOutlineViewDataSource protocol in Swift. One of the functions required by the protocol is:
optional func outlineView(_ outlineView: NSOutlineView,
numberOfChildrenOfItem item: AnyObject?) -> Int
That function requires that you return the number of children of the item parameter. In my code, if the item has any children, they will be stored in an array, var children: [Person]?
I don't initialize that array until I actually add a child to the array.
In other words, at the time that I am providing data to the NSOutlineView, children could be nil or it could be populated, or it could have once been populated but subsequently had all objects removed from it, in which case it won't be nil but it's count will be 0. NSOutlineView doesn't care if children is nil - all it wants to know is how many rows it will need to display the item's children.
So, it makes perfect sense in this situation to return 0 if children is nil. The only reason for calling the function is to determine how many rows NSOutlineView will need. It doesn't care whether the answer is 0 because children is nil or because it is empty.
return (children?.count ?? 0) will do what I need. If children is nil it will return 0. Otherwise it will return count. Perfect!
That looks like the simpler way.
The Objective-C code is shorter only because nil is also a form of 0, being a C-based language.
Since swift is strongly typed you don't have such a shorthand. In this specific case it requires a little more effort, but in general it saves you most of the headaches caused by loose typing.
Concerning the specific case, is there a reason for making the array optional in the first place? You could just have an empty array. Something like this might work for you:
var myArray: Array<String> = []
func numberOfObjectsInMyArray() -> Int {
return myArray.count
}
(Source for this information)
How about using optional for return value?
var myArray: Array<String>?
func numberOfObjectsInMyArray() -> Int? {
return myArray?.count
}
I think that this way is safer.
(Source for this information)

can the keyword "foreach" get the array parameter?

I am a beginner of the scala. many concepts aren't clear for me.
I want to ask that if the foreach can get (or control) the array parameter ?
for example:
val array = Array.ofDim[Double](2,6)
I can use for to control the array's parameter, like
for( i <- 0 until 2){
for(j <- 0 until 6){
......... }}
I can use i,j control and get the parameter. Is "foreach" can do that??
(I know foreach can do things without the parameter, but I just want to ask if it can get
the array parameter?)
thank you :)
I'm not exactly sure what you're asking. If you're asking how to loop over the full array item-by-item, then you can do that without nesting for comprehensions. This will print the contents of your 2D array:
for (row <- array; col <- row) println(col)
If you're asking how to loop over all the indices of the array (I think maybe that's what you mean when you say parameter), then you can use the indices property:
for (i <- array.indices; j <- array(i).indices) println(array(i)(j))
If you're just trying to do indexOf across a 2D array, you can probably just reuse the solution for indexOf for 2D Vector in Scala. This is how I'd adapt it to your code:
val array = Array.tabulate(2,6)(_*6+_)
val searchValue = 8
val indices: Option[(Int, Int)] =
(for {
i <- array.indices
j <- array(i).indices
if (array(i)(j) == searchValue)
} yield (i, j)).headOption
If none of the values match, you'll get indices = None. In this case there is a match, so you get indices = Some((1,2)), because 8 is at array(1)(2).
(Note: Unlike indexOf, using a for comprehension does not short-circuit as soon as it finds the solution. If you make the index ranges lazy by calling .iterator, .view or .toStream then you'll get the expected short-circuiting behavior.)
U can use the function [ indexOf(elem: T): Int ] that will return the position
Scala Array

Resources