Groovy 使用元编程添加collectWithIndex和injectWithIndex,类似于每个WithIndex

Groovy 使用元编程添加collectWithIndex和injectWithIndex,类似于每个WithIndex,groovy,Groovy,请帮助进行元编程配置,以便我可以添加名为collectWithIndex和injectWithIndex的集合方法,这些方法的工作方式与每个WithIndex类似,但当然包括collect和Injection的基本功能。新方法将接受两个(带映射的三个)参数闭包,就像每个Withindex一样。我希望能够跨许多不同的脚本使用这些方法 用例: List one = [1, 2, 3] List two = [10, 20, 30] assert [10, 40, 90] == one

请帮助进行元编程配置,以便我可以添加名为collectWithIndex和injectWithIndex的集合方法,这些方法的工作方式与每个WithIndex类似,但当然包括collect和Injection的基本功能。新方法将接受两个(带映射的三个)参数闭包,就像每个Withindex一样。我希望能够跨许多不同的脚本使用这些方法

用例:

List one = [1, 2, 3]
    List two = [10, 20, 30]
    assert [10, 40, 90] == one.collectWithIndex { value, index ->
    value * two [index]
    }
一旦开发了该方法,那么如何将其提供给脚本?我怀疑会创建一个带有特殊扩展名信息的jar文件,然后将其添加到类路径中


提前非常感谢

我仍然确信,这不是一个合适的SO问题,但我会给你一个例子,如何为你的多个脚本丰富元类

这个想法基于basescript,将所需的方法添加到List的元类的构造函数中。您必须自己实现collect逻辑,这非常简单。你可以用包装纸

import org.codehaus.groovy.control.CompilerConfiguration

class WithIndexInjector extends Script {
    WithIndexInjector() {
        println("Adding collectWithIndex to List")
        List.metaClass.collectWithIndex {
            int i = 0
            def result = []
            for (o in delegate) // delegate is a ref holding initial list.
                result << it(o, i++) // it is closure given to method
            result
        }
    }

    @Override Object run() {
        return null
    }
}

def configuration = new CompilerConfiguration()
configuration.scriptBaseClass = WithIndexInjector.name
new GroovyShell(configuration).evaluate('''
    println(['a', 'b'].collectWithIndex { it, id -> "[$id]:$it" })
''')
// will print [[0]:a, [1]:b]

离题:在SO社区中,您当前的问题只会吸引负面影响,而不会吸引答案。

SO不是一个您要求他人编写代码的地方。你应该试着自己去做,如果你在这期间面临着特定的问题——问一个特定的问题,并将你目前的进展包括在内。这样,您将显示您的报告和迄今为止取得的进展。如果是一个特性请求,请在groovy中提交,或者在邮件列表中点击。看。如果我能了解闭包和函数编程,我会发布代码的。我不知道如何编写一个名为collectWithIndex的方法,该方法是从以闭包为参数的列表或映射对象执行的。我已经添加了一个答案。小心,其他人会减去你,忽略这个问题。老实说,他们是对的。或者干脆做
['a','b','c'].indexed().收集{index,val->[val,index]}
['a','b','c'].indexed().注入([]){list,index,val->list@tim_yates很酷,它是smth new。我没有注意到它被添加了=)。AFAICS这是一个映射转换,因此有很大的内存权衡,~2*N用于转换和访问。但它确实很好。答案被接受,但担心问题的回答没有说明这将如何应用于制作新的collectWithIndex和injectWithIndex方法可用于多个脚本,除非每个脚本都必须包含示例中的所有代码,并且原始脚本包装在evaluate方法中。请原谅,但我不理解这是如何脱离主题的。这是一个带有Groovy标记的Groovy问题。
List.metaClass.collectWithIndex {
    def wrappingProxyClosure = { Closure collectClosure, int startIndex = 0 ->
        int i = startIndex
        return {
            collectClosure(it, i++) // here we keep hold on outer collectClosure and i, and use call former with one extra argument. "it" is list element, provided by default collect method.
        }
    }
    delegate.collect(wrappingProxyClosure(it))
}