c# – 如何将多个表数据结构合并到一个表结果结构中?

假设我有两个查询结果存储在两个不同的.csv文件(1.csv,2.csv)中,数据如下所示:

> 1.csv:

enter image description here

> 2.csv

enter image description here

dim1& dim2将出现在每个查询表结果中,字段可以不同.

我怎样才能得到这样的结果?

>结果

enter image description here

这些字段在结果表中唯一连接,并且行按键(dim1和dim2)分组

我使用了List< List< string>>表示每个表结果:

public static List<List<string>> R1 { get; } = new List<List<string>>
    {
        new List<string> {"dim1", "dim2", "field1"},
        new List<string> {"2", "wwa", "3"},
        new List<string> {"1", "arr", "6"}
    };

    public static List<List<string>> R2 { get; } = new List<List<string>>
    {
        new List<string> {"dim1", "dim2", "field2", "field3"},
        new List<string> {"2", "jaja", "1000", "2"},
        new List<string> {"3", "wwa", "1000", "3"},
        new List<string> {"1", "arr", "2000", "4"}
    };

我采取了以下策略:

var keys = 2;
        var results = new List<List<string>>();

        foreach (var r1 in R1)
        {
            var range = r1.GetRange(0, keys);
            var hash = range.GetKey();
            var found = false;

            var row = new List<string>();
            foreach (var r2 in R2)
            {
                if (r2.GetRange(0, keys).GetKey() == hash)
                {
                    row.AddRange(range);
                    row.AddRange(r1.GetRange(keys, r1.Count - keys));
                    row.AddRange(r2.GetRange(keys, r2.Count - keys));
                    results.Add(row);
                    found = true;
                }
            }
            if (!found)
            {
                row.AddRange(r1);
                R2[0].GetRange(keys, R2[0].Count - keys).ForEach(e => row.Add(null));
                results.Add(row);
            }
        }

        foreach (var r2 in R2)
        {
            var range = r2.GetRange(0, keys);
            var hash = range.GetKey();
            var found = false;

            var row = new List<string>();
            foreach (var r in results)
            {
                if (r.GetRange(0, keys).GetKey() == hash)
                    found = true;
            }
            if (!found)
            {
                row.AddRange(range);
                R1[0].GetRange(keys, R1[0].Count - keys).ForEach(e => row.Add(null));
                row.AddRange(r2.GetRange(keys, r2.Count - keys));
                results.Add(row);
            }
        }

如您所见,我有2xN ^ 2的复杂性,我认为应该有更好的解决方案来生成新的List< List< string>>适合上面的例子.

最佳答案
List连接可以按如下方式完成

 private void JoinList(List<List<string>> listToJoin, int keysNumber, int paddingAfterKeys = 0)
    {
        // you need the padding if an element is found only in the second list
        // this is a list that will be added to the result 
        var paddingList = new List<string>();
        for (var i = 0; i < paddingAfterKeys; i++)
        {
            // feel free to change it to null or what value fit your solution
            paddingList.Add("0");
        }
        foreach (var t in listToJoin)
        {
            // create a key
            var keyString = string.Join(',', t.Take(keysNumber));
            if (result.TryGetValue(keyString, out var fieldsList))
            {
                // if the key already exist just add the values except the keys values this way you won't get duplicate keys
                fieldsList.AddRange(t.Skip(keysNumber));
            }
            else
            {
                // get the keys, pad the list if needed and the rest of the keys
                fieldsList = t.Take(keysNumber).ToList();
                fieldsList.AddRange(paddingList);
                fieldsList.AddRange(t.Skip(keysNumber));
                // add new key to the dictionary and set the value in my program the result was a private variable of the class for the ease of use.
                result[keyString] = fieldsList;
            }
        }
    }

如果密钥不是第一个,您可以执行一个列表来保存索引并从索引中获取密钥.

为了协调这个,你需要这样的东西:

public void ProcessLists()
    {
       const int keysNumber = 2;
       var totalLength = R1[0].Count + R2[0].Count - keysNumber;
       // add first list to dictionary
       JoinList(R1, keysNumber);
       var paddingAfterKeys = R1[0].Count - keysNumber;
       // add the second list to dictionary and add padding if a key was not found in dictionary
       JoinList(R2, keysNumber, paddingAfterKeys);

       // add padding to the end if a key was found in first list but not in second
       paddingAfterKeys = R2[0].Count - keysNumber;

       var paddingList = new List<string>();
       for (var i = 0; i < paddingAfterKeys; i++)
       {
           paddingList.Add("0");
       }
       foreach (var keyValuePair in result.Where(x => x.Value.Count < totalLength))
       {
          keyValuePair.Value.AddRange(paddingList);
       }
    }

转载注明原文:c# – 如何将多个表数据结构合并到一个表结果结构中? - 代码日志