C# linq合并多维字符串数组

C# linq to merge multidimentional string array

我正在寻找简单的 LINQ 来解决这个问题:

//Input
string[,] arr = new string[,]
{
    {"AA:10/BB:20/CC:30","AA:10/BB:20/CC:30","A:10/BB:20/CC:30"},
    {"AA:10/BB:20/CC:30/DD:40","AA:10/BB:20/CC:30","A:10/BB:20/CC:30"},
    {"AA:10/BB:20/CC:30","AA:10/BB:20/CC:30","A:10/BB:20/CC:30"},
};
//Expected output
string[] res = new string[]
{
    "AA:30/BB:60/CC:90/DD:40","AA:30/BB:60/CC:90","BF:30/INF:30"
};

我尝试过的解决方案。

// input   
string[] breakups = new string[]
{
 "YQ:50/BF:50/YR:50",
 "YQ:50/SR:50",
 "YQ:50/BF:50/YR:50",
 "XX:10"
};
//code
string test = string.Join("/", breakups
                        .SelectMany(m => m.Split('/'))
                        .Select(x => x.Split(':'))
                        .GroupBy(m => m[0])
                        .Select(m => string.Format("{0}:{1}", m.Key, m.Sum(g => double.Parse(g[1])))));
//Output
string[] res = new string[]
 {
     "YQ:150/BF:100/YR:100/SR:50/XX:10"
 };

但是如果输入是多维的,我会失败。请指导我解决这个问题

我得到了我喜欢的答案

int columnCount = (arr.Split('@').ToArray()).Select(eac => eac.Split('|')).ToArray()[0].Length;
    var rowList = string.Join("|", from res in (arr.Split('@').ToArray()).Select(eac => eac.Split('|')).ToArray().SelectMany(x => x).Select((x, i) => new { V = x, Index = i }).
                    GroupBy(x => (x.Index + 1) % columnCount).Select(g => g.Select(x => x.V).ToList()).ToList()
                                   select string.Join("/", res
                                            .SelectMany(m => m.Split('/'))
                                            .Select(x => x.Split(':'))
                                            .GroupBy(m => m[0])
                                            .Select(m => string.Format("{0}:{1}", m.Key, m.Sum(g => double.Parse(g[1]))))));

我认为求和的查询有点矫枉过正。我永远不想在这样的事情中寻找错误 ;-) 在这种情况下,传统 解决方案会更合适:

Program-class:

class Program
{
    static void Main(string[] args)
    {
        // Test data.
        string[,] data = new string[,]
        {
            { "AA:10/BB:20/CC:30", "AA:10/BB:20/CC:30", "A:10/BB:20/CC:30" },
            { "AA:10/BB:20/CC:30/DD:40" ,"AA:10/BB:20/CC:30", "A:10/BB:20/CC:30" },
            { "AA:10/BB:20/CC:30", "AA:10/BB:20/CC:30", "A:10/BB:20/CC:30" },
        };

        var result = SumColumns(data);
    }

    // Loops through columns and sums up the values.
    static string[] SumColumns(string[,] data)
    {
        List<Column> columns = new List<Column>();
        for (int i = 0; i < data.GetLength(0); i++)
        {
            Column column = new Column();
            for (int j = 0; j < data.GetLength(1); j++)
            {
                column.Add(data[j, i]);
            }
            columns.Add(column);
        }
        // Convert all columns back into strings.
        return columns.Select(x => x.ToString()).ToArray();
    }
}

Column-class 汇总值:

class Column
{
    Dictionary<string, int> sums = new Dictionary<string, int>();

    public void Add(string data)
    {
        // First split on '/'.
        var dataSplitted = data.Split('/');
        foreach (var item in dataSplitted)
        {
            // Second split on ':'.
            var itemSplitted = item.Split(':');
            string name = itemSplitted[0];

            // Try to get the last sum and add the current value:
            int sum = 0;
            sums.TryGetValue(name, out sum );
            sums[name] = sum + int.Parse(itemSplitted[1]);
        }
    }

    // Creates a string from the sums.
    public override string ToString()
    {
        return 
            sums
            .Select(kvp => string.Format("{0}:{1}", kvp.Key, kvp.Value))
            .Aggregate((result, next) => result + "/" + next);
    }
}