locked
GroupBy - Error Operator / cannot be applied to operands of type IEnumerable<float> and float RRS feed

  • Question

  • Hi, 

    I have the following records

    A=0, B=1, C=4

    A=0, B=2, C=1

    A=1, B=2, C=2

    A=2, B=0, C=3

    I want to be able to GroupBy A and divide each C by the SUM of the GroupBy A ot produce the below

    A=0, C=4, Cfraction = 0.8      // 0.8 = 4 / (4+1)

    A=0, C=4, Cfraction = 0.2     //  0.2 = 1 / (4+1

    A=1, C=4, Cfraction = 1.0

    A=2, C=4, Cfraction = 1.0

    var finalresult = records
                                         .GroupBy(a => a.A)
                                         .Select(row => new 
                                         {
                                             A = row.Key,
                                             Cfraction = (row.Select(c => (float)c.C) / row.Sum(csum => (float)csum.C)) //DOES NOT COMPILE Operator / cannot be applied to operands of type IEnumerable<float> and float
                                         }).ToList();




    Friday, September 11, 2015 3:30 AM

Answers

  • I am not that solid with LINQ, but I am pretty sure you can't do it like that in SQL either. You have to do it in two steps there. I asume it is the same for LINQ.

    Here is how I would do it in SQL, should be translateable to LINQ fairly easily:

    1. Group and Sum:

    SELECT A, C, SUM(C) = 'sumOfC' FROM TABLE source GROUP BY (A)

    You have to keep original C around for the 2nd step to work on the first ones result.

    2. Get teh fraction from that intermediate result:

    SELECT A, C/sumOfC = 'fraction' FROM (/*The querry from step 1*/) GROUP BY (A)

    • Edited by Christopher84 Friday, September 11, 2015 11:03 AM
    • Proposed as answer by DotNet Wang Thursday, September 24, 2015 3:27 AM
    • Marked as answer by Kristin Xie Thursday, September 24, 2015 7:02 AM
    Friday, September 11, 2015 11:03 AM
  • row is an IGrouping that contains several records and you cannot divide a collection of objects with a float. That's what the compiler tells you.

    And the expected result you have posted is not grouped by A since you have two records where A = 0.

    You could first store the sum of C for each A in a Dictionary and then lookup the sum in this dictionary for each row in records. This will produce the expected results:

    List<Record> records = new List<Record>();
    records.Add(new Record() { A = 0, B = 1, C = 4 });
    records.Add(new Record() { A = 0, B = 2, C = 1 });
    records.Add(new Record() { A = 1, B = 2, C = 2 });
    records.Add(new Record() { A = 2, B = 0, C = 3 });
    
    var group = records.GroupBy(a => a.A).ToDictionary(row=>row.Key, row=>row.Sum(csum => (float)csum.C));
    
    var finalresult = records.Select(row => new { A = row.A, Cfraction = (float)row.C / group[row.A] }).ToList();
    

     

    Hope that helps.

    Please remember to close your threads by marking helpful posts as answer and then start a new thread if you have a new question. Please don't ask several questions in the same thread.

    • Proposed as answer by DotNet Wang Thursday, September 24, 2015 3:27 AM
    • Marked as answer by Kristin Xie Thursday, September 24, 2015 7:02 AM
    Friday, September 11, 2015 12:33 PM

All replies

  • I am not that solid with LINQ, but I am pretty sure you can't do it like that in SQL either. You have to do it in two steps there. I asume it is the same for LINQ.

    Here is how I would do it in SQL, should be translateable to LINQ fairly easily:

    1. Group and Sum:

    SELECT A, C, SUM(C) = 'sumOfC' FROM TABLE source GROUP BY (A)

    You have to keep original C around for the 2nd step to work on the first ones result.

    2. Get teh fraction from that intermediate result:

    SELECT A, C/sumOfC = 'fraction' FROM (/*The querry from step 1*/) GROUP BY (A)

    • Edited by Christopher84 Friday, September 11, 2015 11:03 AM
    • Proposed as answer by DotNet Wang Thursday, September 24, 2015 3:27 AM
    • Marked as answer by Kristin Xie Thursday, September 24, 2015 7:02 AM
    Friday, September 11, 2015 11:03 AM
  • row is an IGrouping that contains several records and you cannot divide a collection of objects with a float. That's what the compiler tells you.

    And the expected result you have posted is not grouped by A since you have two records where A = 0.

    You could first store the sum of C for each A in a Dictionary and then lookup the sum in this dictionary for each row in records. This will produce the expected results:

    List<Record> records = new List<Record>();
    records.Add(new Record() { A = 0, B = 1, C = 4 });
    records.Add(new Record() { A = 0, B = 2, C = 1 });
    records.Add(new Record() { A = 1, B = 2, C = 2 });
    records.Add(new Record() { A = 2, B = 0, C = 3 });
    
    var group = records.GroupBy(a => a.A).ToDictionary(row=>row.Key, row=>row.Sum(csum => (float)csum.C));
    
    var finalresult = records.Select(row => new { A = row.A, Cfraction = (float)row.C / group[row.A] }).ToList();
    

     

    Hope that helps.

    Please remember to close your threads by marking helpful posts as answer and then start a new thread if you have a new question. Please don't ask several questions in the same thread.

    • Proposed as answer by DotNet Wang Thursday, September 24, 2015 3:27 AM
    • Marked as answer by Kristin Xie Thursday, September 24, 2015 7:02 AM
    Friday, September 11, 2015 12:33 PM