简体   繁体   English

使用键将对象数组转换为数组对象

[英]Transforming Object Array to Object of Arrays with keys

My Current Structure: 我目前的结构:

input:
[
   {A:A1, B:B1, C:C1, D:D1, E:E1, F:F1, G:G1, H:H1},
   {A:A2, B:B2, C:C2, D:D2, E:E2, F:F2, G:G2, H:H2},
   {A:A3, B:B3, C:C3, D:D3, E:E3, F:F3, G:G3, H:H3}
   ...
]

My Goal: 我的目标:

output
[
   {"A":[A1, A2, A3 ...]},
   {"B":[B1, B2, B3 ...]},
   {"C":[C1, C2, C3 ...]},
   {"D":[D1, D2, D3 ...]},
   {"E":[E1, E2, E3 ...]},
   {"F":[F1, F2, F3 ...]},
   {"G":[G1, G2, G3 ...]},
   {"H":[H1, H2, H3 ...]}
]

Where "A", "B", "C"... are the literal keys from the original objects, and they are now keys in an object to an array of all values of their type. 其中“ A”,“ B”,“ C” ...是原始对象的文字键,现在它们是对象中指向其所有类型的值的数组的键。 This is usually simple except for the fact that I need to maintain the keys throughout 这通常很简单,除了我需要始终维护密钥

This is what I've tried so far but I'm not sure if my loop structure is correct. 到目前为止,这是我尝试过的方法,但是我不确定我的循环结构是否正确。

def ArrayList invertReponse(ArrayList input){

    def output = new ArrayList()

    for(i=0;i<input[0].size();i++){ 

        def tempObj = {}
        def j=0
        input[0].each{ key, value ->            
            tempObj[[input][0][i]][j] = value
            j++
        }
        output.push(tempObj)
    }   
    return output
}

Depending on the assumptions you can make about the input, you might want to start with something like this: 根据您可以对输入进行的假设,您可能要从以下类似的内容开始:

def input = [[A:'A1', B:'B1', C:'C1'],
             [A:'A2', B:'B2', C:'C2'],
             [A:'A3', B:'B3', C:'C3']]

def result = input.inject([:]) { map1, map2 ->
    (map1.keySet() + map2.keySet())
        .inject([:]) {m, k -> m[k] = (map1[k] ?: []) + (map2[k] ?: []); m}
}

result will end up being [A:[A1, A2, A3], B:[B1, B2, B3], C:[C1, C2, C3]] . result将最终为[A:[A1, A2, A3], B:[B1, B2, B3], C:[C1, C2, C3]]

I hope that helps. 希望对您有所帮助。

EDIT: 编辑:

After re-reading the question I see now that what you really want as a result is a List that contains a bunch of Map that each have just 1 key in them. 重新阅读了问题之后,我现在看到的是,您真正想要的是一个包含一堆Map的List,每个Map中只有一个键。 This may be closer to what you want... 这可能更接近您想要的...

def input = [[A:'A1', B:'B1', C:'C1'],
             [A:'A2', B:'B2', C:'C2'],
             [A:'A3', B:'B3', C:'C3']]

def result = []
input.inject([:]) { map1, map2 ->
    (map1.keySet() + map2.keySet())
        .inject([:]) {m, k -> m[k] = (map1[k] ?: []) + (map2[k] ?: []); m}
}.each { k, v ->
    result << [(k):v]
}

With that, result will be [[A:[A1, A2, A3]], [B:[B1, B2, B3]], [C:[C1, C2, C3]]] . 这样, result将是[[A:[A1, A2, A3]], [B:[B1, B2, B3]], [C:[C1, C2, C3]]]

Another way would be to leverage the power of higher order functions as: 另一种方法是利用高阶函数的功能,例如:

def list = [
   [A:'A1', B:'B1', C:'C1', D:'D1', E:'E1', F:'F1', G:'G1', H:'H1'],
   [A:'A2', B:'B2', C:'C2', D:'D2', E:'E2', F:'F2', G:'G2', H:'H2'],
   [A:'A3', B:'B3', C:'C3', D:'D3', E:'E3', F:'F3', G:'G3', H:'H3']
]

// Flexibility on merge condition by provding a Closure
Map mergeOn(Map one, Map two, Closure closure) {
  two.inject([:] << one) { acc, key, val ->
    key in acc.keySet() ? acc[key] = closure(acc[key], val) : acc << [(key): val]
    acc
  }
}

assert list.inject { acc, item -> 
  mergeOn(acc, item) { a, b -> 
    a instanceof List ? a << b : [a, b] 
  } 
}.collect { k, v -> [(k) : v] } == [
   [A: ['A1', 'A2', 'A3']],
   [B: ['B1', 'B2', 'B3']],
   [C: ['C1', 'C2', 'C3']],
   [D: ['D1', 'D2', 'D3']],
   [E: ['E1', 'E2', 'E3']],
   [F: ['F1', 'F2', 'F3']],
   [G: ['G1', 'G2', 'G3']],
   [H: ['H1', 'H2', 'H3']]
]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM