Proliges
Proliges

Reputation: 361

C# check if items in a List<t> exist and increment if it does

I got a CSV file that I read and get 3 values from. The values are: name, date, volume.

I want to do the following, read the file and write it to a List<T> but with a little change. For each item in the CSV file I want to check if the List<T> already contains a line with that name and date. If it does I want the volume in the list increased with +1 if it does not it has to add the line from the csv file to the List<T> with volume = 1

So basically i want something like this.

 List<T> CsvList = new List<T>();
 foreach (var item in CSV)
 {
     object o = new object(item.name, item.date, item.volume)
     if(CsvList.name.contains(o.name) && CsvList.date.contains(o.date){
     //Increase the volume of the item in the CsvList where name == o.name and date == o.date;
     }
 }

Is this possible to achieve in only a C# application. I can write it to a database and check in that database if those values exist, but I don't want to do this with a database.

Upvotes: 0

Views: 1660

Answers (2)

atlaste
atlaste

Reputation: 31116

From what I understand from the question, here goes:

Count the number of times

If you just want to know how often an item occurs, you can use a Dictionary with some key. The key can be a Tuple<string, string> or anything else that's IEquatable (implements Equals and GetHashCode).

e.g.:

Dictionary<Tuple<string, string>, int> dict;
int count;
var key = new Tuple<string, string>(name, date);
dict.TryGetValue(key, out count); // defaults to 0.
dict[key] = count + 1;

Lookup & change

Similarly, if you want to modify the class T (note: it cannot be a struct!), you can use a Dictionary<Tuple<string, string>, T> and store the Name and Date's in the dictionary.

Also, you might want to add a condition like public class CsvReader<T> where T : ISomeInterfaceAllowingModification so you know T to have a property or method that you can use for the changes.

Something like this:

// "T read" is the read line from the CSV.

T value;
var tup = new Tuple<string, string>(name, date);
if (myDictionary.TryGetValue(tup, out value))
{
    // modify value by calling the interface method / using the interface property
    value.AddVolume();
}
else 
{
    // add value to list and dictionary
    myDictionary.Add(tup, read);
    myList.Add(read);
}

Upvotes: 1

Hari Prasad
Hari Prasad

Reputation: 16956

I would suggest using GroupBy linq extension for this.

Group them on (name,date) and calculate the volume count

CSV.GroupBy(x=> new {x.name, x.date})
   .Select(x=>  new object(x.Key.name, x.Key.date, x.Sum(s=> s.volume))) 
                // I'm not sure are you referring to system.object? use appropriate type.
                // or remove object so that you will have an anonymous object.
   .ToList();

Upvotes: 3

Related Questions