セイロン386 333 252 230 222 216 171 153 131 111
String t(String s,Integer l)=>s.size<l then s else s[0:(s[0:l-2].lastIndexWhere(" -".contains)else l-3)]+"...";
Ungolfedオリジナル:
String truncate(String text, Integer length) {
if(text.size < length) {
return text;
}
Boolean spacePredicate(Character char) {
return char == ' ' || char == '-';
}
Integer? spaceIndex = text[0:length-2].lastIndexWhere(spacePredicate);
if(exists spaceIndex) {
return text[0:spaceIndex] + "...";
}
return text[0:length-3]+"...";
}
これは386バイト/文字です。ここでいくつかの興味深い機能:
x[y:z]
構文はのためのシンタックスシュガーであるx.measure(y, z)
、とのサブレンジ返すx
から始まるy
長さをz
-文字列に対して、これはストリングです。(x[y..z]
構文もあります。これは、インデックスyからzまでのスパンであり、両方を含み、ハーフオープンスパンx[...z]
およびx[y...]
。)。
List.lastIndexWhere
述語を取ります(つまり、リスト要素を取り、ブール値を返す関数、つまり、 Callable<Boolean, [Character]>
)、述語が満たされる最後のリスト要素のインデックスを与えます(満たされない場合はnull)。文字列はリストなので、これは文字列でも機能します。
この結果spaceIndex
は、type Integer|Null
またはInteger?
略して-つまり、Integerまたはnull
(typeの唯一の値Null
)のいずれかです。(名前spaceIndex
は、それ-
が特別なものであることに気づかなかったときに由来します。breakIndex
ます。より良います。)
を使用しexists spaceIndex
てspaceIndex
、null以外であるかどうかを確認し、別の操作を実行できます。(このifブロックの内部では、コンパイラはそれがnullでないことを知っています...spaceIndex
文字列にアクセスするためした。)
ローカル関数の代わりに、spacePredicate
匿名関数を使用することもできます
(Character char) => char == ' ' || char == '-'
これにより、333文字になります。
String truncate(String text, Integer length) {
if(text.size < length) {
return text;
}
Integer? spaceIndex = text[0:length-2].lastIndexWhere(
(Character char) => char == ' ' || char == '-');
if(exists spaceIndex) {
return text[0:spaceIndex] + "...";
}
return text[0:length-3]+"...";
}
次の最適化は、短い変数名と関数名を使用することです。これにより、81バイト減り、252になります。
String t(String s, Integer l) {
if(s.size < l) {
return s;
}
Integer? i = s[0:l-2].lastIndexWhere(
(Character e) => e == ' ' || e == '-');
if(exists i) {
return s[0:i] + "...";
}
return s[0:l-3]+"...";
}
述語関数は、実際には引数の型を宣言する必要がありません。これは、コンパイラによって推論できます。i
(value
宣言としてマークするためにまだ記述しなければならない)のタイプについても同じです。これで、宣言は1行に収まるほど短くなり、230になりました。
String t(String s, Integer l) {
if(s.size < l) {
return s;
}
value i = s[0:l-2].lastIndexWhere((e) => e == ' ' || e == '-');
if(exists i) {
return s[0:i] + "...";
}
return s[0:l-3]+"...";
}
代わりにe == ' ' || e == '-'
書くこともできますe in [' ', '-']
(またはe in {' ', '-'}
、これはタプルではなく反復可能なコンストラクタです)。in
オペレータは、我々はその組の合格できるという考えに私たちをもたらします方法Category.contains、にマップcontains
することなく、(それはそうも文字を受け入れて、任意のオブジェクトを取る呼び出し可能である)メソッドを直接(e) => ...
定型(222バイト):
String t(String s, Integer l) {
if(s.size < l) {
return s;
}
value i = s[0:l-2].lastIndexWhere([' ', '-'].contains);
if(exists i) {
return s[0:i] + "...";
}
return s[0:l-3]+"...";
}
実際、同じ2文字を含む別のカテゴリは2文字の文字列" -"
です。(さらに、サブストリングも含まれていますが、ここでは問題ありません)。216バイト。
String t(String s, Integer l) {
if(s.size < l) {
return s;
}
value i = s[0:l-2].lastIndexWhere(" -".contains);
if(exists i) {
return s[0:i] + "...";
}
return s[0:l-3]+"...";
}
私たちはこの行を最大限に活用したと思いますが、他のものに目を向けてみましょう...最後の2つのreturn文は利用できるいくつかの類似性を持っています-それらは単にi
vs. l-3
で異なり、i
それがnullでないときだけ使用していますl-3
。幸いなことに、これはまさにelse
オペレーターの目的です!
String t(String s, Integer l) {
if(s.size < l) {
return s;
}
value i = s[0:l-2].lastIndexWhere(" -".contains);
return s[0:(i else l-3)] + "...";
}
(括弧else
は、より優先順位が低いため、ここで必要なようです[:]
。)これは171文字です。Now i
は1回だけ使用されるため、インライン化して153文字にできます。
String t(String s, Integer l) {
if(s.size < l) {
return s;
}
return s[0:(s[0:l-2].lastIndexWhere(" -".contains) else l-3)] + "...";
}
また、このif-return-return
組み合わせを1つののthen
and else
演算子の組み合わせに置き換えることもできreturn
ます。(then
最初のオペランドがtrueの場合、returnsは2番目のオペランド、それ以外の場合はnullで、2番目のオペランドelse
を返すことができます)。
String t(String s, Integer l) {
return s.size < l then s else s[0:(s[0:l-2].lastIndexWhere(" -".contains) else l-3)] + "...";
}
式とともに1つの戻り値のみを含む関数は、代わりに「太い矢印」表記で記述でき、123が得られます。
String t(String s, Integer l) =>
s.size < l then s else s[0:(s[0:l-2].lastIndexWhere(" -".contains) else l-3)] + "...";
不要な空白を削除すると、最後の111バイトが得られます。
String t(String s,Integer l)=>s.size<l then s else s[0:(s[0:l-2].lastIndexWhere(" -".contains)else l-3)]+"...";
さらに、質問の例を出力する関数があります(t
ステップ2の後に使用される名前を使用)。
shared void testTruncate() {
value testInputs = {
["This is some very long text.", 25],
["This-is-some-long-hyphen-separated-text.", 33],
["Programming Puzzles & Code Golf is a question and answer site for programming puzzle enthusiasts and code golfers.", 55],
["abcdefghijklmnopqrstuvwxyz", 20],
["a b c", 4],
["Very long.", 100]
};
for(input in testInputs) {
print(t(*input));
}
}