Reputation: 1097
I apologize upfront, because I now realize that I have completely worded my example wrong. For those who have given responses, I truly appreciate it. Please let me re-attempt to explain with a more accurate details. Please edit your responses, and once again, I apologize for not being more exact in my previous posting.
Using an entity framework model class called Staging (which is a representation of my Staging table), I have the following List<Staging>
.
List<Staging> data = (from t in database.Stagings select t).ToList();
//check for an empty List...react accordingly...
Here is a quick look at what Staging
looks like:
public partial class Staging
{
public int ID { get; set; } //PK
public int RequestID { get; set; } //FK
...
public string Project { get; set; }
...
}
Let us suppose that the query returns 10 records into my data
list. Let us also suppose that data[3]
, data[6]
, and data[7]
each have the same value in data.Project
, let's say "Foo"
. The data.Project
value is not known until runtime.
Given this, how would I keep the first occurrence, data[3]
, and remove data[6]
and data[7]
from my List<Staging>
?
Edit: I have the following code that works, but is there another way?
HashSet<string> projectValuesFound = new HashSet<string>();
List<Staging> newData = new List<Staging>();
foreach (Staging entry in data)
{
if (!projectValuesFound.Contains(entry.Project))
{
projectValuesFound.Add(entry.Project);
newData.Add(entry);
}
}
Upvotes: 1
Views: 1028
Reputation: 52117
The "canonical" way to do it would be to pass appropriately implemented comparer to Distinct:
class Var3Comparer : IEqualityComparer<MyClass> {
public int GetHashCode(MyClass obj) {
return (obj.Var3 ?? string.Empty).GetHashCode();
}
public bool Equals(MyClass x, MyClass y) {
return x.Var3 == y.Var3;
}
}
// ...
var distinct = list.Distinct(new Var3Comparer());
Just beware that while current implementation seems to keep the ordering of the "surviving" elements, the documentation says it "returns an unordered sequence" and is best treated that way.
There is also a Distinct overload that doesn't require a comparer - it just assumes the Default comparer, which in turn, will utilize the IEquatable<T> if implemented by MyClass
.
Upvotes: 0
Reputation: 150108
You could use Linq:
var result = (from my in theList where my.Var3 == "Foo" select my).First();
If you also want to keep the other items, you can use Distinct() instead of First(). To use Dictinct(), either MyClass
must implement IEquatable<T>
, or you must provide an IEqualityComparer<T>
as shown in the MSDN link.
Upvotes: 0
Reputation: 1587
var uniques = (from theList select theList.Var3).Distinct();
That will give you distinct values for all entries.
Upvotes: 0
Reputation: 564433
You can do this via LINQ and a HashSet<T>
:
var found = new HashSet<string>();
var distinctValues = theList.Where(mc => found.Add(mc.Var3));
// If you want to assign back into the List<T> again:
// theList = distinctValues.ToList();
This works because HashSet<T>.Add
returns true if the value was not already in the set, and false if it already existed. As such, you'll only get the first "matching" value for Var3
.
Upvotes: 2