web-dev-qa-db-ja.com

インデックス付きの.collect

ありますか .collectインデックス付き?私はこのようなことをしたいです:

def myList = [
    [position: 0, name: 'Bob'],
    [position: 0, name: 'John'],
    [position: 0, name: 'Alex'],
]

myList.collect { index ->
    it.position = index
}

(つまり、positionをリスト内の順序を示す値に設定したい)

42
zoran119

Groovy 2.4.0以降、_Java.lang.Iterable_に追加される withIndex() メソッドがあります。

したがって、機能的な方法(副作用なし、不変)では、次のようになります。

_def myList = [
  [position: 0, name: 'Bob'],
  [position: 0, name: 'John'],
  [position: 0, name: 'Alex'],
]

def result = myList.withIndex().collect { element, index ->
  [position: index, name: element["name"]] 
}
_
87
Beryllium

CollectWithIndexのややグルーヴィーなバージョン:

List.metaClass.collectWithIndex = {body->
    def i=0
    delegate.collect { body(it, i++) }
}

あるいは

List.metaClass.collectWithIndex = {body->
    [delegate, 0..<delegate.size()].transpose().collect(body)
}
13
Matt

eachWithIndexはおそらくもっとうまくいくでしょう:

myList.eachWithIndex { it, index ->
    it.position = index
}

コレクションを変更するだけで、コレクションの特定の部分を新しいコレクションに返さないので、collectXを使用する必要はありません。

12
Rob Hruska

これはまさにあなたが望むことをするはずです

List.metaClass.collectWithIndex = {cls ->
    def i = 0;
    def arr = [];
    delegate.each{ obj ->
        arr << cls(obj,i++)
    }
    return arr
}



def myCol = [
    [position: 0, name: 'Bob'],
    [position: 0, name: 'John'],
    [position: 0, name: 'Alex'],
]


def myCol2 = myCol.collectWithIndex{x,t -> 
    x.position = t
    return x
}

println myCol2

=> [[position:0, name:Bob], [position:1, name:John], [position:2, name:Alex]]
7
dstarh

拡張メソッドを追加しなくても、非常に簡単な方法でこれを行うことができます。

def myList = [1, 2, 3]
def index = 0
def myOtherList = myList.collect {
  index++
}

ただし、このメソッドが自動的に存在することは確かに役立ちます。

5
pickypg

dstarh のように、インデックスが入力された新しいマップを返す非破壊的なメソッドを探していない限り、 Rob Hruska の答えが探しているものですために。

dstarh の答えは、collectWithIndexの非破壊バージョンを提供しますが、結果の実際のコレクションも処理します。

ポリモーフィックなcollect実装でニースを再生するために、つまり特定のクラスがcollectを異なる方法で実装する場合(結果を単に置くよりも)配列の場合)collectWithIndexデリゲートがあると、動作が均一になります。コードは次のようになります。

@Category(List)
class Enumerator {
    def collectWithIndex(Closure closure) {
        def index = 0
        this.collect { closure.call(it, index++) }
    }
}

use(Enumerator) {
    ['foo', 'bar', 'boo', 'baz'].collectWithIndex { e, i ->
        [index: i, element: e]
    }
}

eachWithIndexcollectWithIndexの例については、 this Gist を参照してください。

また、質問の状態へのコメントと同様に、説明した機能について2つのJira課題が公開されています- GROOVY-238GROOVY-3797

1
dexterous