开发者

How to write this for iteration in scala without using the For( loop; if condition) and still use yield properlly

开发者 https://www.devze.com 2023-04-04 16:28 出处:网络
Hi I am a Scala student not really a lot of experience in it. I been trying to make something like this

Hi I am a Scala student not really a lot of experience in it.

I been trying to make something like this

object FileMatcher {
    private def filesHere = (new java.io.File(".")).listFiles

    private def filesMatching(matcher: String => Boolean) =
        for (file <- filesHere; if matcher(file.getName))
            yield file.getName

    def filesEnding(query: String) = filesMatching(_.endsWith(query))
    def filesContaining(query: String) = filesMatching(_.contains(query))
    def filesRegex(query: String) = filesMatching(_.matches(query))
}

work with this syntax ( I honestly don't like or have reached the ilumination to undestand why shoud I use FORs like that yet. maybe it will come... )

object FileMatcher {
    private def filesHere = (new java.io.File(".")).listFiles

    private def filesMatching(matcher: String => Boolean) =
        for (file <- filesHere)
                 yield
            if (matcher(file.getName))
                file.getName

    def filesEnding(query: String) = filesMatching(_.endsWith(query))
    def filesContaining(query: String) = filesMatching(_.contains(query))
    def filesRegex(query: String) = filesMatching(_.matches(que开发者_开发问答ry))
}

So what I would like to know is

How can I yield a value without getting the return of the If in this last form ?

Right now my outputs with this running this :

FileMatcher.filesEnding("scala")

in the order of code show are

***.scala

and the next goes

(),(),(),(),***.scala,(),(),()

Because the if is returning it's values.


The first expression

for (file <- filesHere; if matcher(file.getName))
        yield file.getName

due to for comprehension is translated to

filesHere.filter(file => matcher(file.getName)).map(file => file.getName)

where file => file.getName returns String on filtered collection.
and the second one

for (file <- filesHere)
             yield
        if (matcher(file.getName))
            file.getName

translated to

filesHere.map(file => if (matcher(file.getName)) file.getName)

where file => if (matcher(file.getName)) file.getName rerurns Any which you can see in output as ()


How about this:

private def filesMatching(matcher: String => Boolean) =
  filesHere.filter(file => matcher(file.getName)).map(file => file.getName)
0

精彩评论

暂无评论...
验证码 换一张
取 消