define ['a', 'b', 'c'], (A, B, C,) ->
I want write
define
['a', 'b', 'c']
, (A, B, C,) ->
How to do it without a compiler error ?
define(
['a', 'b', 'c']
(A, B, C) ->
"D"
)
Which compiles to:
define(['a', 'b', 'c'], function(A, B, C) {
return "D";
});
As a general rule, if you have multiple arguments that you want to be comma separated in the output but line separated in the input, put them at the same indent level.
The parentheses after the define are necessary to tell the compiler that there is a set of things that need to be passed into the function.
The comma after the C in your input was causing an error as well.
First, you have to get rid of the trailing comma in your anonymous function's argument list. Then you have a few options:
define \
['a', 'b', 'c']
(A, B, C) ->
Be careful that the backslash doesn't have anything other than a newline after it. Or you could add parentheses:
define(
['a', 'b', 'c']
(A, B, C) ->
)
but be very careful that you don't leave any space between define and ( or you'll get an accidental JavaScript comma operator in the JavaScript version.
Related
I have this structure:
Seq[(Int, mutable.Set[List[A]])]
and my aim is flatten it in order to obtain a structure like List[List[A]].
In particular, my structure is something like this:
val order = List((1,HashSet(List('o'))), (4,HashSet(List('i', 'j', 'k', 'l'))), (3,HashSet(List('a', 'b', 'c'), List('f', 'g', 'h'))), (2,HashSet(List('d', 'e'), List('m', 'n'), List('z', 'x')))) and i want to obtain something like val order = List( List('o'), List('i', 'j', 'k', 'l'), List('a', 'b', 'c'), ...).
I tried to make a map in this way:
order map {
case (_, Set[List[A]]) => List[A]
}
but it doesn't work. The error is "pattern type is incompatible with expected type".
The same thing also happens with:
case (Seq[(_, Set[List[A]])]) => List[A] and case (Seq[(_, mutable.Set[List[A]])]) => List[A].
I'm pretty sure that to do the flattening, the solution is to use the map (or flatMap), but apparently I'm using it in the wrong way. Anyone have any suggestions / ideas of how I could do it? Thanks!
How about this?
order.flatMap(_._2)
I'm having some trouble transposing lists with uneven amounts of elements. Let's say our data is:
ABC
E
GHI
I want my list to be:
List(List('A','E','G'), List('B',' ','H'), List('C',' ','I'))
I cannot manage to get empty spaces (' ') where I need them. With my code:
val l = List("ABC", "E", "GHI")
println(((l map (_.toArray)) toArray).transpose map (_.toList) toList)
// I get: List(List('A', 'E', 'G'), List('B', 'H'), List('C', 'I'))
A solution may be to get the longest line and add white spaces to the rest of the lines, but it's really not clean. Is there a simple solution to this?
Here is a code-golf solution for an input list l:
(0 until l.map(_.size).max).map(i => l.map(s => Try(s(i)).getOrElse(' ')))
which returns:
Vector(List(A, E, G), List(B, , H), List(C, , I))
This:
Retrieves the maximum length of a string in the input list.
Loop from 0 until the max length of a string in the input list
Within each loop it gets each element's char at the given index.
The Try is used to handle items whose length is shorter than the current index being handled. And these cases return " " instead.
To use Try, you need to import:
import scala.util.Try
One approach is to use padTo, although this will involve multiple traversals of the list:
val l = List("ABC", "E", "GHI")
val maxSize = l.map(_.size).max // 3
val transposed = l.map(_.toList).map(_.padTo(maxSize, ' ')).transpose
// List[List[Char]] = List(List(A, E, G), List(B, , H), List(C, , I))
I want to create a Scala sequence comprising tuples. The input is a text file like this:
A
B
C
D
E
I'm looking for an elegant way to construct "lagged" tuples like this:
(A, B), (B, C), (C, D), (D, E)
The easiest way to do this is by using the tail and zip:
val xs = Seq('A', 'B', 'C', 'D', 'E')
xs zip xs.tail
If efficiency is a concern (i.e. you don't want to create an extra intermediate sequence by calling tail and the Seq you use are not Lists, meaning that tail takes O(n)) then you can use views:
xs zip xs.view.tail
I'm not quite sure how elegant it is, but this will work for at least all lists of more than 1 element:
val l = List('A,'B,'C,'D,'E,'F)
val tupled = l.sliding(2).map{case x :: y :: Nil => (x,y)}
tupled.toList
// res8: List[(Symbol, Symbol)] = List(('A,'B), ('B,'C), ('C,'D), ('D,'E), ('E,'F))
If you want something more elegant than that, I'd advise you look at Shapeless for nice ways to convert between lists and tuples.
Why this code doesn't work:
scala> List('a', 'b', 'c').toSet.subsets.foreach(e => println(e))
<console>:8: error: missing parameter type
List('a', 'b', 'c').toSet.subsets.foreach(e => println(e))
^
But when I split it then it works fine:
scala> val itr=List('a', 'b', 'c').toSet.subsets
itr: Iterator[scala.collection.immutable.Set[Char]] = non-empty iterator
scala> itr.foreach(e => println(e))
Set()
Set(a)
Set(b)
Set(c)
Set(a, b)
Set(a, c)
Set(b, c)
Set(a, b, c)
And this code is OK as well:
Set('a', 'b', 'c').subsets.foreach(e => println(e))
First, there's a simpler version of the code that has the same issue:
List('a', 'b', 'c').toSet.foreach(e => println(e))
This doesn't work either
List('a', 'b', 'c').toBuffer.foreach(e => println(e))
However, these work just fine:
List('a', 'b', 'c').toList.foreach(e => println(e))
List('a', 'b', 'c').toSeq.foreach(e => println(e))
List('a', 'b', 'c').toArray.foreach(e => println(e))
If you go take a look at the List class documentation you'll see that the methods that work return some type parameterized with A, whereas methods that don't work return types parameterized with B >: A. The problem is that the Scala compiler can't figure out which B to use! That means it will work if you tell it the type:
List('a', 'b', 'c').toSet[Char].foreach(e => println(e))
Now as for why toSet and toBuffer have that signature, I have no idea...
Lastly, not sure if this is helpful, but this works too:
// I think this works because println can take type Any
List('a', 'b', 'c').toSet.foreach(println)
Update: After poking around the docs a little bit more I noticed that the method works on all the types with a covariant type parameter, but the ones with an invariant type parameter have the B >: A in the return type. Interestingly, although Array is invariant in Scala they provide two version of the method (one with A and one with B >: A), which is why it doesn't have that error.
I also never really answered why breaking the expression into two lines works. When you simply call toSet on its own, the compiler will automatically infer A as B in the type for the resulting Set[B], unless you do give it a specific type to pick. This is just how the type inference algorithm works. However, when you throw another unknown type into the mix (i.e. the type of e in your lambda) then the inference algorithm chokes and dies—it just can't handle an unknown B >: A and an unknown type of e as well.
I want to convert
console.log({
a: 'a'
}, {
b: 'b'
});
into CoffeeScript. The only way I found is
console.log
a: 'a',
b: 'b'
It seems bizarre that a: 'a' and b: 'b' are not indented the same when they are essentially symetric in this situation.
Put the comma one in a separated line, one indentation level less than the hash/object, so it's treated as part of the function invocation.
console.log
a: 'a'
, # indentation level matters!
b: 'b'
this will not work because the indentation level is the same as hash, so it's treated as part of the hash.
console.log
a: 'a'
,
b: 'b'
Or you could use braces, which do work in CS:
console.log {a:'a'}, {b:'b'}
Well, if you think about the parsing rules,
a: 'a',
b: 'b'
actually means
{ a: 'a', b: 'b' }
Since this isn't the behaviour you want, you need to tell the parser that the line with b: is another object. Indenting will do that for you. Now this wasn't really a question, but I hope it helps you understand why to do it the way you described. It is the right way.
$ coffee -bce 'console.log(a: "a"; b: "b")'
// Generated by CoffeeScript 1.2.1-pre
console.log({
a: "a"
}, {
b: "b"
});