如何动态获取multiGroup IEnumerable

时间:2019-10-28 11:17:25

标签: winforms linq

public class Customer
{
        public string Country { get; set; }
        public string City { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
        public bool IsHasMoney { get; set; }
        public bool IsHasCar { get; set; }

        private List<Customer> customers = new List<Customer>
        {
            new Customer
            {
                Country = "USA",
                City = "NY",
                Name = "John",
                Address = "Brooklin",
                IsHasMoney = true,
                IsHasCar = true
            },
            new Customer
            {
                Country = "USA",
                City = "NY",
                Name = "Piter",
                Address = "Brooklin",
                IsHasMoney = true,
                IsHasCar = true
            },
            new Customer
            {
                Country = "USA",
                City = "NY",
                Name = "Nicolas",
                Address = "Brooklin",
                IsHasMoney = true,
                IsHasCar = true
            },
            new Customer
            {
                Country = "Canada",
                City = "Torotonto",
                Name = "John",
                Address = "Brooklin",
                IsHasMoney = true,
                IsHasCar = true
            }
        };

        public List<Customer> GetAllCustomers()
        {
            return customers;
        }

        public string[] arr = new string[] { "Country", "Country", "Country", "Country", "Country" };
    }

    public class OrderCustomer
    {
        static Customer customer = new Customer();

        private void GetAllGroups(List<Customer> _list, string[] propNames)
        {
            _list = customer.GetAllCustomers();

            foreach (var item in propNames)
            {
                _list = _list.GroupBy(item)..GroupBy(item)..GroupBy(item);
            }
/*new SubGroup will group recursivelly*/
        }
}

我的想法是,每次新的循环迭代,我都会得到一个新的类型IGroup<bla bla bla, Type>

我有一些对象列表,并且有string[] arr个客户属性名称。

我想按arr[]值分组所有子组。

我尝试使用动态Linq,但是出了点问题。

我需要获取所有子组,以便在每个子组的最后一个子组中进行排序。我需要找出解决方法。

如何以递归方式动态获取它?

1 个答案:

答案 0 :(得分:0)

修复代码正常工作后(customers应该为staticarr应该具有不同的属性名称) and improving GetAllGroups to return IEnumerable>`,您可以写以下内容。

首先,是一种用于展平的递归分组的扩展方法:

public static class IEnumerableExt {
    public static IEnumerable<IGrouping<TKey,TRecord>> GroupByMany<TKey,TRecord>(this IEnumerable<IGrouping<TKey, TRecord>> src, Func<TRecord,TKey> keyFn) =>
        src.SelectMany(g => g.GroupBy(r => keyFn(r)));
}

接下来,在Customer中使用静态方法创建一个Func以返回键:

public static Func<Customer, object> KeyLambda(string propName) {
    var parm = Expression.Parameter(typeof(Customer), "c");
    var propInfo = typeof(Customer).GetProperty(propName);
    Expression body = Expression.Property(parm, propInfo);
    if (propInfo.PropertyType.IsValueType)
        body = Expression.Convert(body, typeof(object));
    var lambda = Expression.Lambda<Func<Customer, object>>(body, parm);
    return lambda.Compile();
}

arr的固定定义:

public static string[] arr = new string[] { "Country", "City", "IsHasMoney" };

最后,工作的GetAllGroups

public static IEnumerable<List<Customer>> GetAllGroups(string[] propNames) {
    var wlist = customer.GetAllCustomers().GroupBy(Customer.KeyLambda(propNames[0]));

    foreach (var item in propNames.Skip(1))
        wlist = wlist.GroupByMany(Customer.KeyLambda(item));

    return wlist.Select(cg => cg.ToList());
}

可以像这样使用:

var ans = OrderCustomer.GetAllGroups(Customer.arr);