1

Suppose I have a list with a Tuple.First as a string[] (i.e. my key):

var lst = new List<Tuple<string[], int>> {
     new Tuple<string[], int>(new string[] { "A", "B" }, 5),
     new Tuple<string[], int>(new string[] { "A", "B" }, 10),
     new Tuple<string[], int>(new string[] { "C", "B" }, 10),
}

I would like to aggregate (e.g. Sum) by Tuple.First (i.e. string[]) so expecting an output as follows:

var output = new List<Tuple<string[], int>> {
     new Tuple<string[], int>(new string[] { "A", "B" }, 15),
     new Tuple<string[], int>(new string[] { "C", "B" }, 10),
}

I did it this way but there must be a cleaner way to do it instead of forcing a pipe concatenation:

var output = lst
    .GroupBy(x => string.Join("|", x.First))
    .Select(x => new Tuple<string[], int>( 
             x.Key.Split('|'),   
             Sum(x => x.Second)));
3
  • why object (array) is a key? Commented Jan 27, 2021 at 18:52
  • I want to group by string[] Commented Jan 27, 2021 at 18:53
  • Where does the Pair class come from? How do you access the values that you pass to its constructor? Commented Jan 27, 2021 at 18:56

1 Answer 1

2

You need to implement IEqualityComparer for string[]. My example using touples (You don't say what Pair is):

static void Main(string[] args)
{
    var lst = new List<(string[] arr, int num)> {
        (new string[] { "A", "B" }, 5),
        (new string[] { "A", "B" }, 10),
        (new string[] { "C", "B" }, 10),
    };

    var grouped = lst.GroupBy(pair => pair.arr, new EnumerableComparer());
    var sums = grouped.Select(g => (arr: g.Key, num: g.Sum(p => p.num)));
}

class EnumerableComparer<TRecord> : IEqualityComparer<IEnumerable<TRecord>>
    {
        public bool Equals(IEnumerable<TRecord> x, IEnumerable<TRecord> y)
        {
            return ReferenceEquals(x, y) || x != null && x.SequenceEqual(y);
        }

        public int GetHashCode(IEnumerable<TRecord> lst)
        {
            unchecked
            {
                int hash = 387;
                foreach (var elem in lst)
                {
                    hash = hash * 31 + elem.GetHashCode();
                }

                return hash;
            }
        }
    }
Sign up to request clarification or add additional context in comments.

2 Comments

@Denis what was wrong with using native HashCode class?
It wouldn't resolve with R#. Maybe it needs a high version of .Net?

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.