我在Ceylon中有一个序列,我想根据索引创建一个新的序列,其中一个元素被其他元素替换:
[String*] strings = ["zero", "one", "two"];
value index = 1;
value newElement= "uno";
[String*]? newStrings = ???; // should be ["zero", "uno", "two"]
在Scala中,这称为update
。
答案 0 :(得分: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()
来创建一个懒惰的元素流,然后{{1操作将副本复制到新序列中。它在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);
实例)。
答案 1 :(得分:3)
你可以理解:
[String*] newStrings = [for (i->e in strings.indexed) i==index then newElement else e];
答案 2 :(得分:3)
另一种方法是将它复制到一个 可变的数组,然后再返回:
[String*] strings = ["zero", "one", "two"];
value index = 1;
value newElement= "uno";
value array = Array(strings);
array.set(index, newElement);
[String*] newStrings = array.sequence();