微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

迭代器:将最后一个元素与另一个值配对

如何解决迭代器:将最后一个元素与另一个值配对

在Scala中,我有一个类似于以下内容的List [String]:

val xs = List("apple","orange",...,"pear","dragonfruit")

我想生成以下结果列表:

List(("apple",","),("orange",("pear",("dragonfruit",";"))

请注意,最后一对具有分号而不是逗号。 我可以不知道清单的长度吗?更一般而言,是否有适用于Iterable的功能版本?

def pairUp[A,B](xs: Iterable[A],nonlastB: B,lastB: B): Iterable[(A,B)]

xs中的每个x都应该与nonlastB配对,最后一个lastB配对。

解决方法

为此使用foldRight

在您的示例中,您有

"apple" :: "orange" :: ... :: "pear" :: "dragonfruit" :: Nil

你想要

("apple",",") :: ("orange",") :: ... :: ("pear",") :: ("dragonfruit",";") :: Nil

foldRight的直觉是它可以进行构造函数替换。

l.foldRight采用两个参数。第一个替换构造函数Nil,第二个替换构造函数::,所以您有了l.foldRight(nilReplacement)(consreplacement)现在,让我们看一下您想要为Nil和{ {1}}:

::
  • "apple" :: "orange" :: ... :: "pear" :: "dragonfruit" :: Nil ("apple",";") :: Nil 停留在Nil
  • Nil成为x :: Nil
  • (x,";") :: Nil成为x :: other

如此

(x,") :: other

不幸的是,您会发现val nilReplacement = Nil val consReplacement = { case x :: Nil => (x,";") :: Nil case x :: other => (x,") :: other } xs.foldRight(nilReplacement)(consReplacement) 不能正确地进行类型检查,因为没有预期的类型,并且它会很快推断出val consreplacement的错误类型。但是提供足够的类型提示可以解决该问题:

Nil

一种完全不同的方法可以通过迭代直接实现:

xs.foldRight[(String,String)](Nil) {
  case x :: Nil   => (x,") :: other
}

您可以使用stdlib中稍微复杂的import scala.collection.mutable.Builder def pairUp[A,B](as: Iterable[A],nonlastB: B,lastB: B): Iterable[(A,B)] = { val it = as.iterator val builder = as.iterableFactory.newBuilder[(A,B)] def loop(prev: A): Unit = { if (it.hasNext) { builder.addOne(prev -> nonlastB) loop(it.next()) } else builder.addOne(prev -> lastB) } if(it.hasNext) loop(it.next()) builder.result() } 基础结构来抽象输入类型:

Factory
,

我将建议2个选项,它可能比此处建议的其他答案效率低。但是它们很简单而且简短。

首先,删除最后一个元素,然后在以后添加它:

class Basis
{
public:
    virtual int function(int i = 1) { return 2; }
};

class Sub : public Basis
{
public:
    int function(int i = 5) override { return i; }
};

int main()
{
    Basis* a[2];
    a[0] = new Sub();
    cout << a[0]->function(); //gives 1
}

我想到的第二个选择就是在xs.dropRight(1).map(l => (l,nonlastB)) ++ xs.lastOption.map(last => (last,lastB)) 上滑动,并用分号显式添加最后一个项目:

iterable

代码运行可以在Scastie上找到。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。