Is there any way to leverage Groovy's collect method in combination with another iterator function?

后端 未结 2 1049
無奈伤痛
無奈伤痛 2020-12-20 08:13

For example, the groovy File class has a nice iterator that will filter out just directories and not files:

void eachDir(Closure closure) 

2条回答
  •  半阙折子戏
    2020-12-20 08:31

    I don't know of any "idiomatic" way of doing this, nice riddle! =D

    You can try passing the eachDir, or any similar function, to a function that will collect its iterations:

    def collectIterations(fn) {
        def col = []
        fn {
            col << it
        }
        col
    }
    

    And now you can use it as:

    def dir = new File('/path/to/some/dir')
    def subDirs = collectIterations(dir.&eachDir)
    
    def file = new File('/path/to/some/file')
    def lines = collectIterations(file.&eachLine) 
    

    (that last example is equivalent to file.readLines())

    And only for bonus points, you may define this function as a method in the Closure class:

    Closure.metaClass.collectIterations = {->
        def col = []
        delegate.call {
            col << it
        }
        col
    }
    
    def dir = new File('/path/to/some/dir')
    def subDirs = dir.&eachDir.collectIterations()
    
    def file = new File('/path/to/some/file')
    def lines = file.&eachLine.collectIterations()
    

    Update: On the other hand, you might also do:

    def col = []    
    someDir.eachDir col.&add
    

    Which I think is quite less convoluted, but it's not leveraging the collect method as you requested :)

提交回复
热议问题