2

我经常遇到这种情况。我有一批这种格式的数据(存储在 CSV、XML 中,没关系):

key1|value1
key1|value2
key1|value3
key2|value4
key2|value5
etc.

并且需要能够以这种形式处理它:

data[key1] => [value1, value2, value3]
data[key2] => [value4, value5]
etc.

从 A 转换为 B 的最佳方法是什么?我通常像这样循环遍历列表(伪代码),但我不喜欢我必须重复我的数组构建代码。

data = []
values = []
currentKey = ""
foreach (line in inputData) {
    key, value = split(line)
    if ((currentKey != "") and (currentKey != key)) {
        data[currentKey] = values
        values = []
    }
    currentKey = key
    values.add(value)
}
// this is the part I don't like, but it's necessary to capture the last group
data[currentKey] = values

我没有特别指定一种语言,因为我必须至少在 Javascript、C#、Perl 和 PHP 中这样做。如果有特定于语言的解决方案会很棒,但我真的在寻找最有效的通用算法方法。

4

2 回答 2

1

这是一个解决方案。首先,创建地图。对于数据文件中的每个条目,找到键和值。检查钥匙是否在地图中。如果不是,则向包含该键的新值的映射添加一个新列表。如果键已经在映射中,只需将新值添加到列表中。

def hash = [:]
new File("test.data").eachLine { String line ->
    def (key,value)  = line.split(/\|/)
    hash.get(key, []) << value
}

println hash

它打印出以下地图:

[key1:[value1, value2, value3], key2:[value4, value5]]

无需跟踪currentKey

编辑:这是用 Groovy 编写的,但应该在其他语言中非常相似地实现。hash.get()返回键的值,或提供的默认值(在上面的代码片段中,一个空列表),而左移 ( <<) 运算符向列表中添加一些内容。

于 2012-08-02T17:53:53.713 回答
1

您可以将代码更改为:

data = {}

currentKey = ""

foreach (line in inputData) {

    key, value = split(line)
    if (currentKey != key) {
        data[key] = [] // like data.put(key,new ArrayList<String>()) in java
    }
    data[key].add(value) // like data.get(key).add(value) in java
    currentKey = key
}
于 2012-08-02T17:17:58.507 回答