LINQ C # - combining multiple groups

LINQ Groupby query creates a new group for each unique key. I would like to combine multiple groups into one group based on the key value.

eg.

var customersData = new[] 
{
    new { id = 1, company = "ABC" },
    new { id = 2, company = "AAA" },
    new { id = 3, company = "ABCD" },
    new { id = 4, company = "XYZ" },
    new { id = 5, company = "X.Y.Z." },
    new { id = 6, company = "QQQ" },
};

var groups = from d in customersData 
             group d by d.company;

      

Let's say I want ABC, AAA and ABCD in the same group, and XYZ, XYZ in the same group.

Is there anyway to achieve this via LINQ queries?

+2


source to share


5 answers


You will need to use the GroupBy overload, which accepts IEqualityComparer.

var groups = customersData.GroupBy(k => k.company, new KeyComparer());

      

where KeyComparer might look like


public class KeyComparer : IEqualityComparer
{
    public bool Equals(string x, string y)
    {
        // put your comparison logic here 
    }

    public int GetHashCode(string obj)
    {
        // same comparison logic here
    }
}

      



You can compare strings however you like in the Equals KeyComparer method.

EDIT:

You also need to make sure that the GetHashCode implementation obeys the same rules as the Equals method. For example, if you just removed the "." and replace with "" as in other answers, you need to do it in both methods like this


public class KeyComparer : IEqualityComparer
{
    public bool Equals(string x, string y)
    {
        return x.Replace(".", "") == y.Replace(".", "");
    }

    public int GetHashCode(string obj)
    {
        return obj.Replace(".", "").GetHashCode();
    }
}

      

+6


source


I am assuming the following:

  • You wanted to have quotes surrounding company names (as shown below).
  • Your problem is simply solved by deleting '. on behalf of each company.

If these assumptions are correct, then the solution is simply the following:



var customersData = new[] {
    new { id = 1, company = "ABC" },
    new { id = 2, company = "A.B.C." },
    new { id = 3, company = "A.B.C." },
    new { id = 4, company = "XYZ" },
    new { id = 5, company = "X.Y.Z." },
    new { id = 6, company = "QQQ" },
};

var groups = from d in customersData
             group d by d.company.Replace(".", "");

      

If these assumptions are wrong, please clarify and I can help you get closer to a solution.

+4


source


var groups = from d in customersData 
             group d by d.company.Replace(".", "");

      

0


source


public void int GetId(Company c)
{
  int result = //whatever you want
  return result;
}

      

and then:

var groups = from d in customersData
             group d by GetId(d.company);

      

0


source


I think this is what you want:

        var customersData = new[]  
        { 
            new { id = 1, company = "ABC" }, 
            new { id = 2, company = "AAA" }, 
            new { id = 3, company = "ABCD" }, 
            new { id = 4, company = "XYZ" }, 
            new { id = 5, company = "X.Y.Z." }, 
            new { id = 6, company = "QQQ" }, 
        };

        var groups = from d in customersData
                     group d by d.company[0];

        foreach (var group in groups)
        {
            Console.WriteLine("Group " + group.Key);
            foreach (var item in group)
            {
                Console.WriteLine("Item " + item.company);
            }
        }
        Console.ReadLine();

      

0


source







All Articles