Как получить мультигруппу IEnumerable динамически - PullRequest
0 голосов
/ 28 октября 2019
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 голосов
/ 28 октября 2019

После исправления кода (customers должно быть static, arr должно иметь разные имена свойств ) 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...