Scalaでゴルフをするための一般的なヒントは何ですか?私は、少なくともScalaに特有のゴルフ問題全般のコーディングに適用できるアイデアを探しています(たとえば、「コメントの削除」は答えではありません)。回答ごとに1つのヒントを投稿してください。
Scalaでゴルフをするための一般的なヒントは何ですか?私は、少なくともScalaに特有のゴルフ問題全般のコーディングに適用できるアイデアを探しています(たとえば、「コメントの削除」は答えではありません)。回答ごとに1つのヒントを投稿してください。
回答:
免責事項:この回答の一部は、ここにある他の回答の一般化です。
次のようなものを送信することができます:のa=>a.size
代わりに(a:String)=>a.size
。
これらにはが含まれます!%&/?+*~'-^<>|
。彼らは手紙を聞かないので、彼らは手紙の隣にいるとき、彼らは分離されて解析されます。
例:
a=>b //ok
%=>% //error, parsed as one token
% => % //ok
val% =3 //ok
&contains+ //ok
if(x)&else* //ok
if (Seq(1,2,3,'A')contains x)... //wrong
if (Set(1,2,3,'A')(x))... //right
これは可能ですSet[A] extends (A => Boolean)
。
(a,b)=>... //wrong
a=>b=>... //right
_
可能な場合は-syntaxを使用しますこれのルールはやや曖昧です。最短の方法を見つけるために、時々遊んでいる必要があります。
a=>a.map(b=>b.size)) //wrong
a=>a.map(_.size) //better
_.map(_.size) //right
a=>a+1 //wrong
_+1 //better, see above
1+ //right; this treats the method + of 1 as a function
""+
代わりに使用toString
a=>a.toString //wrong
a=>a+"" //right
""
アクチュアタイプを気にしない場合、空のシーケンスを作成する最も簡単な方法である場合があります
10以外の基数で数値を文字列に変換する最短の方法は、BigIntのtoString(base: Int)
メソッドを使用することです
Integer.toString(n,b) //wrong
BigInt(n)toString b //right
文字列を数値に変換する場合は、使用します BigInt.apply(s: String, base: Int)
Integer.parseInt(n,b) //wrong
BigInt(n,b) //right
これはBigIntを返すことに注意してください。これはほとんどの場合に使用できますが、たとえばシーケンスのインデックスとして使用することはできません。
a::b::Nil //wrong
List(...) //also wrong
Vector(...) //even more wrong
Seq(...) //right
Array(...) //also wrong, except if you need a mutable sequence
文字のシーケンスに文字列を使用する:
Seq('a','z') //wrong
"az" //right
いくつかの課題は、無限シーケンスのn番目の要素を要求します。ストリームはこれに最適な候補です。ことを忘れないでくださいStream[A] extends (Int => A)
ストリームは、そのインデックスの要素のインデックスからの機能である、つまり、。
Stream.iterate(start)(x=>calculateNextElement(x))
:\
そして:/
代わりにfoldRight
とfoldLeft
a.foldLeft(z)(f) //wrong
(z/:a)(f) //right
a.foldRight(z)(f) //wrong
(a:\z)(f) //right
hashCode
-> ##
throw new Error()
-> ???
&
andの|
代わりに&&
andを使用します||
ブール値でも同じように機能しますが、常に両方のオペランドを評価します
def r(x:Double)=math.sqrt(x) //wrong
var r=math.sqrt _ //right; r is of type (Double=>Double)
これは特にコレクションのメソッドに適用されます。
非常に便利な方法は次のとおりです。
map
flatMap
filter
:/ and :\ (folds)
scanLeft and scanRight
sliding
grouped (only for iterators)
inits
headOption
drop and take
collect
find
zip
zipWithIndex3
distinct and/or toSet
startsWith
使用できますか?識別子として:
val l=List(1,2,3)
val? =List(1,2,3)
ここでは、等号に固定できないため、何も保存されません。
val ?=List(1,2,3) // illegal
ただし、後で区切り文字が必要ないため、多くの場合1文字が保存されます。
print(?size) // l.size needs a dot
def a(? :Int*)=(?,?tail).zipped.map(_-_)
ただし、次を使用するのは難しい場合があります。
print(?size)
3
print(?size-5)
<console>:12: error: Int does not take parameters
print(?size-5)
^
ランダムコレクションの最初の選択肢は、多くの場合Listです。多くの場合、これをSeqに置き換えることができます。これにより、1文字のインスタントが保存されます。:)
の代わりに
val l=List(1,2,3)
val s=Seq(1,2,3)
また、通常のコードでs(0)
はs.headとs.tailはよりエレガントですが、ここでも1文字短くなっていs.head
ます。
場合によってはさらに短くなります-必要な機能に応じてタプルがあります:
val s=Seq(1,2,3)
val t=(1,2,3)
3文字をすぐに保存し、アクセスするために:
s(0)
t._1
直接インデックスアクセスの場合も同じです。ただし、詳細な概念の場合、タプルは失敗します。
scala> s.map(_*2)
res55: Seq[Int] = List(2, 4, 6)
scala> t.map(_*2)
<console>:9: error: value map is not a member of (Int, Int, Int)
t.map(_*2)
^
def foo(s:Seq[Int])
def foo(s:Int*)
パラメーター宣言では、Int *はSeq [Int]に4文字を保存します。同等ではありませんが、Int *で十分な場合があります。
より短いタイプを定義する:
次のような型の宣言が複数ある場合
def f(a:String,b:String,c:String)
型エイリアスを定義し、代わりに使用する方が短いです:
type S=String;def f(a:S,b:S,c:S)
元の長さは3 * 6 = 18です。置換コードは8(タイプS =;)+ 6 + 3 * 1(=新しい長さ)= 17です。
(n * length <8 + length + n)の場合、それは利点です。
ファクトリを介してインスタンス化されるクラスの場合、そのオブジェクトを指すように短い変数名を設定できます。の代わりに:
val a=Array(Array(1,2),Array(3,4))
私たちは書くことができます
val A=Array;val a=A(A(1,2),A(3,4))
def
はメソッドを定義するためのキーワードであり、c ++ forへの単純な変換val
は 'const'であり、それは宣言ですが、型はしばしば推測されます。短縮は、最初のケースtype=
ではに近いtypedef
-そうではありませんか?2番目の例は私からのものではなく、私にとって新しいものです。私はそれをどこで使用するかに気をつけなければなりません。
typedef long long ll;
#define ll long long
はと同じなので、後者は1だけ短くなりますが、typedef
動作します。val
例をもう一度見ると、私は間違いなく誤解しています。Scala特有ではないようです。 x = thingWithAReallyLongComplicatedNameForNoReason
はかなり一般的な戦略です:P
List
or Array
などをインスタンス化するときは、オブジェクトのメソッドをval x = List(1,2,3)
呼び出すだけです。(オブジェクト作成のこの手法は、でコンストラクタを使用するのとは対照的に、「ファクトリーメソッド」として知られています。)上記では、変数nameと同じシングルトンオブジェクトを指す新しい変数を作成しています。同じことなので、を含むすべてのメソッドが利用可能です。apply
List
new
Array
apply
#define
、たとえばC ++にも当てはまりますが、それは良いことでdef
ありval
、より短いことを認めます。