锡兰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)]+"...";
无纸化原稿:
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]
语法,这是一个跨度从索引j到z,包括两个端点,以及半开跨度x[...z]
和x[y...]
)。
List.lastIndexWhere
接受一个谓词(即,一个函数接受一个list元素并返回一个布尔值,即a Callable<Boolean, [Character]>
),并给出满足该谓词的最后一个list元素的索引(如果从未满足,则返回null)。因为字符串是列表,所以它也适用于字符串。
其结果spaceIndex
是type Integer|Null
或Integer?
简称-即它可以是Integer或null
(type的唯一值Null
)。(这个名字spaceIndex
来自我不知道那-
也很特别的时候–我想breakIndex
会更好。)
通过exists spaceIndex
我们可以检查是否spaceIndex
为非空,然后做一些不同的事情。(在此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
标记为声明)。现在声明很短,只能放在一行上,使我们降至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]+"...";
}
实际上,另一个包含相同两个字符的类别是两个字符的string " -"
。(此外,它还包含其子字符串,但这在这里没有影响)。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]+"...";
}
我想我们可以从这条线中得到最大的收益,让我们转向其他...最后两个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个字符。现在i
只使用了一次,因此我们可以内联它,使我们拥有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
的组合代替此组合。(第一个操作数为true时,return 为第二个操作数,否则为null,然后允许返回其第二个操作数。)131个字节(尽管有些节省是我们总要摆脱的空白):then
else
return
then
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)] + "...";
}
可以只用一个表达式返回一个函数的函数也可以用“胖箭头”符号写成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
在第二步之后使用的名称):
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));
}
}