セイロン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文は利用できるいくつかの類似性を持っています-それらは単にivs. 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つののthenand 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));
}
}