1

I am looking for simple LINQ to solve this:

//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"
};

My tried solution.

// 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"
 };

But I fail if input is multidimentional. Please guide me to solve this

I got answer as I like

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]))))));
5
  • possible duplicate of C# LINQ to merge two breakup Commented Jan 9, 2015 at 14:14
  • Dude you already asked this question and got your answers. Voting to close as duplicate. This can and will be considered spam. Commented Jan 9, 2015 at 14:14
  • If you need the multidimensional arrays use loops instead of LINQ. Commented Jan 9, 2015 at 14:15
  • Linq will "flatten" a multi-dimensional array. You could use a jagged array (string[][]) or a for loop, but you cannot use linq to loop through "rows" of a 2-D array. Commented Jan 9, 2015 at 14:16
  • That question is for one dimensional array. But now I am asking for mulch-dimentional array. Commented Jan 9, 2015 at 14:17

1 Answer 1

1

The query to sum this is an overkill I think. I would never like to look for a bug in something like this ;-) A traditional solution in this case would be much more appropriate:

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 that sums up the values:

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);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Absolutely agreed.The LINQ solution looks convoluted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.