Search code examples
c#linqtuplesyield-return

How to return tuple with IEnumerable<(string category, IEnumerable<Product> productsName)> with linq


Well I have to return result in tuple's format, but because of nested foreach loops, i can't use yield return (tuple). What should i do?

public static IEnumerable<(string category, IEnumerable<Product> productsName)> GroupJoinQuery()
{
            string[] categories =
            {
                "Vegetables",
                "Dairy Products",
                "Seafood"
            };

            List<Product> products = Products.ProductList;

            var q = categories.GroupJoin(products, c => c, p => p.Category, (c, ps)
=> new { Category = c, Products = ps });

            foreach (var v in q)
            {
                Console.WriteLine($"{v.Category}:");
                foreach (var p in v.Products)
                {
                    Console.WriteLine($"   {p.ProductName}");
                }
            }
        }

Solution

  • Since you wish to return one element per category, with the second component of the tuple being an IEnumerable of products matching the category, the following will work fine:

    public static IEnumerable<(string category, IEnumerable<Product> productsName)> GroupJoinQuery()
    {
        string[] categories =
        {
                    "Vegetables",
                    "Dairy Products",
                    "Seafood"
                };
    
        List<Product> products = Products.ProductList;
    
        return (IEnumerable<(string category, IEnumerable<Product> productsName)>) 
            categories.GroupJoin(products, c => c, p => p.Category, (c, ps)
            => new { Category = c, Products = ps.ToArray() });
    }
    

    Note the use of ToArray(). If products is ultimately populated by a database and the IEnumerable is iterated after a required context is disposed, you would get a runtime exception. The call to ToArray() materializes the result (copies it to memory). For modest result sizes, this is an acceptable strategy. If the result set is substantial, you may wish to consider a different approach.