我在锡兰有一个序列,我想制作一个新序列,其中一个元素根据索引替换为其他元素:
[String*] strings = ["zero", "one", "two"];
value index = 1;
value newElement= "uno";
[String*]? newStrings = ???; // should be ["zero", "uno", "two"]
在 Scala 中,这称为update
.
我在锡兰有一个序列,我想制作一个新序列,其中一个元素根据索引替换为其他元素:
[String*] strings = ["zero", "one", "two"];
value index = 1;
value newElement= "uno";
[String*]? newStrings = ???; // should be ["zero", "uno", "two"]
在 Scala 中,这称为update
.
有几种方法可以解决这个问题,我喜欢上面Quintesse的解决方案,使用Array
. 这也许就是我在实践中会做的事情。但是,该Array
解决方案有一个可能很重要的缺点:它分配了两次内存。
因此,为了完整起见,让我建议几个不同的选项:
这有效,但有点冗长:
[String*] strings = ["zero", "one", "two"];
value index = 1;
value newElement= "uno";
[String*] newStrings =
strings.take(index)
.chain(strings.skip(index+1).follow(newElement))
.sequence();
请注意,这里我们使用惰性流操作take()
、skip()
和来创建元素的惰性流chain()
,follow()
然后将sequence()
操作复制到新序列中。它只分配一次,在调用sequence()
.
patch()
这也有效:
[String*] strings = ["zero", "one", "two"];
value index = 1;
value newElement= "uno";
[String*] newStrings =
strings.patch([newElement], index, 1)
.sequence();
请注意,如果它足以取回不可变的List
,您可以放弃对 的调用sequence()
,从而导致:
[String*] strings = ["zero", "one", "two"];
value index = 1;
value newElement= "uno";
[String*] newStrings =
strings.patch([newElement], index, 1);
在这种情况下,根本没有分配(除了一个微不足道的实例List.Patch
)。
你可以通过理解来做到这一点:
[String*] newStrings = [for (i->e in strings.indexed) i==index then newElement else e];
另一种方法是将其复制到一个可变数组中,然后返回:
[String*] strings = ["zero", "one", "two"];
value index = 1;
value newElement= "uno";
value array = Array(strings);
array.set(index, newElement);
[String*] newStrings = array.sequence();