更新不可变序列
Updating an immutable sequence
我在 Ceylon 有一个序列,我想制作一个新序列,根据索引将其中一个元素替换为其他元素:
[String*] strings = ["zero", "one", "two"];
value index = 1;
value newElement= "uno";
[String*]? newStrings = ???; // should be ["zero", "uno", "two"]
在 Scala 中,这称为 update
。
你可以理解一下:
[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();
有几种方法可以解决这个问题,我做喜欢上面Quintesse的解决方案,使用Array
。这也许就是我在实践中会做的事情。但是,Array
解决方案有一个 possibly-important 缺点:它分配内存 两次 。
为了完整起见,让我提出几个不同的选择:
使用流操作
这有效,但有点冗长:
[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
的一个微不足道的实例)。
我在 Ceylon 有一个序列,我想制作一个新序列,根据索引将其中一个元素替换为其他元素:
[String*] strings = ["zero", "one", "two"];
value index = 1;
value newElement= "uno";
[String*]? newStrings = ???; // should be ["zero", "uno", "two"]
在 Scala 中,这称为 update
。
你可以理解一下:
[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();
有几种方法可以解决这个问题,我做喜欢上面Quintesse的解决方案,使用Array
。这也许就是我在实践中会做的事情。但是,Array
解决方案有一个 possibly-important 缺点:它分配内存 两次 。
为了完整起见,让我提出几个不同的选择:
使用流操作
这有效,但有点冗长:
[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
的一个微不足道的实例)。