바로 가기를 만들기 위한 지도에서 목록에서 묘?
-
09-06-2019 - |
문제
나는 다음과 같은 일부 sorthand 이:
Map rowToMap(row) {
def rowMap = [:];
row.columns.each{ rowMap[it.name] = it.val }
return rowMap;
}
주어진 방법을 사용해 물건입니다,나는 기대를 할 수 있 다음과 같습니다.
Map rowToMap(row) {
row.columns.collectMap{ [it.name,it.val] }
}
그러나 나는 아무것도 보지 않았는 문서에서...나는 뭔가?또는 나는 그냥 너무 게으른?
해결책
나는 최근에 건너 왔어요 정확히 할 필요가있다:변환 목록으로 지도입니다.이 질문을 게시하기 전에 끝내 버전 1.7.9 나온다,그래서 방법 collectEntries
존재하지 않은 아직입니다.그것으로 정확하게 작동 collectMap
방법 는 제안:
Map rowToMap(row) {
row.columns.collectEntries{[it.name, it.val]}
}
는 경우 어떤 이유로 당신은 이전에 그루비 버전 inject
방법도 사용할 수 있습(으로 제안 기).이것은 약간 수정 버전하는 단 하나의 식을 내밈(위해 단지 캐릭터의 저장!):
Map rowToMap(row) {
row.columns.inject([:]) {map, col -> map << [(col.name): col.val]}
}
이 +
연산자를 사용할 수도 있습신 <<
.
다른 팁
Check out"주".진짜 프로그래밍 wonks call it"fold".
columns.inject([:]) { memo, entry ->
memo[entry.name] = entry.val
return memo
}
고,당신이 그것에있는 동안,당신은 아마을 정의하는 방법으로 카테고리가 오른쪽에 metaClass.는 방법을 정의할 수 있습니다 그것은 한 번에 대한 모든 컬렉션:
class PropertyMapCategory {
static Map mapProperty(Collection c, String keyParam, String valParam) {
return c.inject([:]) { memo, entry ->
memo[entry[keyParam]] = entry[valParam]
return memo
}
}
}
를 들어 사용:
use(PropertyMapCategory) {
println columns.mapProperty('name', 'val')
}
였 groupBy 방법을 사용할 수 없을 때 이 질문을 묻?
또한,만약 당신이 사용하여 google 컬렉션(http://code.google.com/p/google-collections/),당신은 다음과 같이 할 수 있다:
map = Maps.uniqueIndex(list, Functions.identity());
ok...나이 좀 더 많은 제 생각에 이것은 정말 멋진 메소드...
def collectMap = {Closure callback->
def map = [:]
delegate.each {
def r = callback.call(it)
map[r[0]] = r[1]
}
return map
}
ExpandoMetaClass.enableGlobally()
Collection.metaClass.collectMap = collectMap
Map.metaClass.collectMap = collectMap
지금 어떤 서브 클래스의 지도하거나 컬렉션가 이 방법은...
여기에서 내가 사용하는 그것을 반대하는 키/값에서 지도
[1:2, 3:4].collectMap{[it.value, it.key]} == [2:1, 4:3]
그리고 여기를 만드는 데 사용 지도서 목록
[1,2].collectMap{[it,it]} == [1:1, 2:2]
지금 나는 그냥 이로 클래스에 가져오라고한 내 응용 프로그램은 시작과 이 방법은 나의 코드입니다.
편집:
를 추가하는 방법을 모두 배열을...
Object[].metaClass.collectMap = collectMap
는 경우에 당신은 무엇이 필요한 간단한 키/값 쌍 다음 방법 collectEntries
충분해야 합니다.예를 들어
def names = ['Foo', 'Bar']
def firstAlphabetVsName = names.collectEntries {[it.charAt(0), it]} // [F:Foo, B:Bar]
하지만 당신이 원하는 구조와 비슷한 Multimap,에있는 여러 값을 키당,다음 사용하고 싶 groupBy
방법
def names = ['Foo', 'Bar', 'Fooey']
def firstAlphabetVsNames = names.groupBy { it.charAt(0) } // [F:[Foo, Fooey], B:[Bar]]
나는 아무것도 찾을 수 없습니다장에서...그러나 사용하여 ExpandoMetaClass 내가 작업을 수행 할 수 있습니다:
ArrayList.metaClass.collectMap = {Closure callback->
def map = [:]
delegate.each {
def r = callback.call(it)
map[r[0]] = r[1]
}
return map
}
이에 추가하 collectMap 방법을 모두 ArrayLists...나는 확실하지 않은 왜 그것을 추가하는 목록 또는 수집하지 않았다.나는 생각한 다른 질문은...그러나 이제는 내가 이것을 할 수 있는...
assert ["foo":"oof", "42":"24", "bar":"rab"] ==
["foo", "42", "bar"].collectMap { return [it, it.reverse()] }
목록에서 계산도 하나의 폐쇄...정확히 무엇을 찾고 있었습니다.
편집:그 이유는 내가 없을 추가하는 방법은 인터페이스 목록하고 수집하지 않았기 때문에 나는 이것:
List.metaClass.enableGlobally()
후에는 메소드 호출에 추가할 수 있습 방법을 인터페이스..이 경우 의미 내 collectMap 방법에서 작동 범위는 다음과 같다:
(0..2).collectMap{[it, it*2]}
을 산출 지도[0:0, 1:2, 2:4]
에 대해 무엇이 같은 뭔가?
// setup
class Pair {
String k;
String v;
public Pair(def k, def v) { this.k = k ; this.v = v; }
}
def list = [ new Pair('a', 'b'), new Pair('c', 'd') ]
// the idea
def map = [:]
list.each{ it -> map.putAt(it.k, it.v) }
// verify
println map['c']