4

Is there a way using LINQ to get a distinct list of items from a list of object array without knowing how many items exist in each array? The number of items in each array item will be the same throughout the list.

        // Foo is a list of object arrays. The number of items
        // each array is non-specific.
        // (In this example there is only 3 items, but there could be 100)
        var foo = new List<object[]>();

        // I add some items to the list.
        foo.Add(new object[] { 1, "Something", true });
        foo.Add(new object[] { 1, "Some Other", false });
        foo.Add(new object[] { 2, "Something", false });
        foo.Add(new object[] { 2, "Something", false });

        // This will get me a distinct list from the array list...
        // but it requires I know how many items are in each array.
        List<object[]> bar = foo.Select(x => new { X1 = x[0], X2 = x[1], X3 = x[2] })
                                 .Distinct()
                                 .Select(x => new object[] { x.X1, x.X2, x.X3 })
                                 .ToList();



        List<object[]> bar = ?? /// < -- How can I rewrite the
        //                                 previous line so that
        //                                 my code works with n array items?

I will know how many items there are at runtime if that helps?

If it is not possible in LINQ, can anyone please suggest a method I could use to achieve the desired results?

2 Answers 2

4

If i understand you right then you can try something like this:

   class Comparer : IEqualityComparer<object[]>
        {
            public bool Equals(object[] x, object[] y)
            {
                if (x.Length != y.Length)
                    return false;

                for (int i = 0; i < x.Length; ++i)
                    if (!x[i].Equals(y[i]))
                        return false;

                    return true;
                }

                public int GetHashCode(object[] obj)
                {
                    return string.Join("", obj).GetHashCode();
                }
        }

     static void Main(string[] args)
        {
            var foo = new List<object[]>();

            foo.Add(new object[] { 1, "Something", true });
            foo.Add(new object[] { 1, "Some Other", false });
            foo.Add(new object[] { 2, "Something", false });
            foo.Add(new object[] { 2, "Something", false });

            var distinctList = foo.Distinct(new Comparer()).ToList();
/*
distinctList now contains
1, "Something", true
1, "Some Other", false
2, "Something", false
*/
        }
Sign up to request clarification or add additional context in comments.

5 Comments

+1 Nice one for this! Can you please explain the GetHashCode() method? How can I do a String.Join() if I don't know if I'll get anything meaningful back from a ToString() method of the object? Am I missing something here?
Does the distinct use the Equals() or the GetHashCode() method? I'd expect one of the two is superfluous for the purpose of this problem... But the real answer lies of course in the IEqualityComparer<T> implementation. Great answer :)
@Beakie Why you can't get anything meaningful from ToString() method?
@oerkelens You are right, Distinct() use GetHashCode() method. Equals() is only for completeness
I am using basic types so it doesn't matter. Thanks for the answer!
-1

Please try with below code

List<object[]> bar  = foo.GroupBy(x => new { X1 = x[0], X2 = x[1], X3 = x[2] }).Select(g => new object[] { g.Key.X1, g.Key.X2, g.Key.X3, g.Count() }).ToList();

Each object has four value and last one for count of group

3 Comments

I am confused? This requires I know how many items there are. This achieves the same as I had previously?
I just updated my answer. you can group column as you want and you may get how many item based on group
@NareshPansuriya You are missing the point. Your code sample explicitly expects 3 items. You need to update it to show it can handle a variable number of items.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.