简体   繁体   中英

Counting and accessing items in a list of lists ie: invoice with line items

I am trying to wrap my head around C# Lists, coming from a strong PHP background and thinking of things in PHP Array terms, but I have a class that includes a list and I am trying to count distint items within it. Is there a simple linq way to do this or would I use some sort of nested foreach?

Thank you in advance

public void main() {
   List<invoice> inv = new List<invoice>();

   // I do something that populates inv with, say 100 invoices

   // Count distinct inv.lines.rowtype ?? to get:
   Type A   34
   Type B   3
   Type X   21 ...etc

}

class invoice {
   int invoicenumber;
   int customernumber;
   List<lineitem> lines;

   struct lineitem {
      string rowtype;
      string somethingelse;
      int whatever;
   }
   public invoice {
      lines = new List<lineitem>;
   }
}

像这样吗

inv.SelectMany(i => i.lines).GroupBy(l => l.rowtype).ToDictionary(g => g.Key, g => g.Count())

You could probably use some LINQ for this, however for the sake of simplicity and readability, I would recommend using for loops

// Keep a dictionary for count
var lineItemDict = new Dictionary<string, int>();
foreach (var inv in invoices)
{
    foreach (var line in inv.lines)
    {
        // If the rowtype already exists, increment the count
        if (lineItemDict.ContainsKey(line.rowtype))
        {
            lineItemDict.TryGetValue(line.rowtype, out count);
            lineItemDict[line.rowtype] = count + 1;
        }
        else
        {
            // Else add a new entry
            lineItemDict.Add(line.rowtype, 1);
        } 
    }
}

With LINQ:

// Keep a dictionary for count
var lineItemDict = new Dictionary<string, int>();
invoices.ForEach(inv => {
    inv.lines.ForEach(line => {
        // If the rowtype already exists, increment the count
        if (lineItemDict.ContainsKey(line.rowtype))
        {
            lineItemDict.TryGetValue(line.rowtype, out count);
            lineItemDict[line.rowtype] = count + 1;
        }
        else
        {
            // Else add a new entry
            lineItemDict.Add(line.rowtype, 1);
        }

    });
});

Both of these will leave you with a dictionary ( lineItemDict ) that looks like this:

<rowtype> : <count>

For example,

'A' : 34
'B' : 3
'X' : 21

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM