Derek
Derek

Reputation: 8628

LINQ with IList<SelectedItemList> Issue

I have a Datatable in which i need to convert each row into a IList

public IList<SelectListItem> _area = new List<SelectListItem>();
public IList<SelectListItem> _team = new List<SelectListItem>();

     foreach (DataRow row in dt.Rows)
            {
       _area.Add(new SelectListItem() { Text = row[1].ToString(), Value = row[1].ToString() });
       _team.Add(new SelectListItem() { Text = row[0].ToString(), Value = row[0].ToString() });

            }

The data that is then obtained in _area looks like this :-

Text                     Value
OMC                      OMC
OMC                      OMC
OMC                      OMC
SIAM                     SIAM
SIAM                     SIAM
SIAM                     SIAM                     
SIAM                     SIAM                     
SIAM                     SIAM

I need to use LINQ to get the DISTINCT Values.

I have tried simply using :-

_area.Distinct();

But i'm left with 32 entries that i started with???

Upvotes: 1

Views: 1649

Answers (3)

Filip Ekberg
Filip Ekberg

Reputation: 36317

The Distinct() method takes a paremter of type IEqualityComparer<T> so in this case, you can create an equality comparer that compares two values of two SelectListItems like this:

public class SelectListItemComparer : IEqualityComparer<SelectListItem>
{
    public static SelectListItemComparer Instance = new SelectListItemComparer();
    private SelectListItemComparer() {}
    public bool Equals(SelectListItem x, SelectListItem y)
    {
        return x.Value.Equals(y.Value);
    }

    public int GetHashCode(SelectListItem obj)
    {
        return obj.Value.GetHashCode();
    }
}

Then you can use it like this:

var items = new[]
                {
                    new SelectListItem {Text = "OMC", Value = "OMC"},
                    new SelectListItem {Text = "OMC", Value = "OMC"},
                    new SelectListItem {Text = "OMC", Value = "OMC"},
                    new SelectListItem {Text = "SIAM", Value = "SIAM"},
                    new SelectListItem {Text = "SIAM", Value = "SIAM"},
                    new SelectListItem {Text = "SIAM", Value = "SIAM"},
                    new SelectListItem {Text = "SIAM", Value = "SIAM"},
                    new SelectListItem {Text = "SIAM", Value = "SIAM"}
                };

var comparer = new SelectListItemComparer();
var t1 = items.Distinct(SelectListItemComparer.Instance).ToList();

t1 will contain only two elements now.

Upvotes: 2

jjchiw
jjchiw

Reputation: 4445

_area.GroupBy(x => x.Value).Select(x => x.Key);

This will give you the distinct values of the areas...

how about like this

_area.GroupBy(x => x.Value).Select(x => x.First());

Can you explain better what is Distinct, maybe you should override Equals and GetHashCode and that way It will work the Distinct, something like this

class Foo
{
    public string Text { get; set; }
    public string Value { get; set; }

    public override bool Equals(object obj)
    {
        var foo = obj as Foo;
        if(foo == null) return false;

        return foo.Text == Text && foo.Value == Value;
    }

    public override int GetHashCode()
    {
        return Text.GetHashCode() * Value.GetHashCode() ^ 7;    
    }
}

and then this will work as you expect (hope so)

_area.Distinct();

Upvotes: 2

JohnnBlade
JohnnBlade

Reputation: 4327

Have you tried this _area = _area.Distinct();

Upvotes: 5

Related Questions