2

我在锡兰有一个序列,我想制作一个新序列,其中一个元素根据索引替换为其他元素:

[String*] strings = ["zero", "one", "two"];
value index = 1;
value newElement= "uno";
[String*]? newStrings = ???; // should be ["zero", "uno", "two"]

在 Scala 中,这称为update.

4

3 回答 3

5

有几种方法可以解决这个问题,我喜欢上面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)。

参阅List.patch().

于 2016-01-19T12:52:06.193 回答
3

你可以通过理解来做到这一点:

[String*] newStrings = [for (i->e in strings.indexed) i==index then newElement else e];

在线尝试

于 2016-01-18T23:04:42.510 回答
3

另一种方法是将其复制到一个可变数组中,然后返回:

[String*] strings = ["zero", "one", "two"];
value index = 1;
value newElement= "uno";

value array = Array(strings);
array.set(index, newElement);

[String*] newStrings = array.sequence();
于 2016-01-19T09:33:52.600 回答