Информация об изменениях

Сообщение Re: Сделать из одного массива - два от 26.11.2022 9:21

Изменено 26.11.2022 10:29 Sinclair

Re: Сделать из одного массива - два
Здравствуйте, snaphold, Вы писали:

S>как из persons одним запросом через Linq получить 2 массива: ages (distinct age from persons), names (distinct name from persons) ?

А зачем вам 1 запросом? Чем не устраивает 2?
(names, ages) = ((from p in persons select p.name).Distinct(), (from p in persons select p.age).Distinct());
S>то есть хотелось бы такого вида получить
S>
S>(names, ages) = persons.SelectMany(x => (n, a), n.Distinct(name), a.Distinct(a.age));
S>

В ФП все такие операции делаются через fold/reduce (Aggregate в .Net).
Тот же самый Distinct выражется через Aggregate вот таким образом:
public IEnumerable<T> Distinct<T>(this IEnumerable<T> source) => 
  source.Aggregate(new ImmutableHashSet<T>(), (set, x) => set.Add(x));

То есть начинаем с пустого множества, а затем каждый из элементов исходной коллекции складываем в это множество (игнорируя дубликаты).
С учётом этого знания, решение от IT выглядит очевидным обобщением:
(names, ages) 
  = persons.Aggregate(
    (names: new ImmutableHasSet<string>(), ages:new ImmutableHashSet<int>()), 
    (acc, person) =>(acc.names.Add(person.name), acc.ages.Add(person.age))
  );
Re: Сделать из одного массива - два
Здравствуйте, snaphold, Вы писали:

S>как из persons одним запросом через Linq получить 2 массива: ages (distinct age from persons), names (distinct name from persons) ?

А зачем вам 1 запросом? Чем не устраивает 2?
(names, ages) = ((from p in persons select p.name).Distinct(), (from p in persons select p.age).Distinct());

S>то есть хотелось бы такого вида получить
S>
S>(names, ages) = persons.SelectMany(x => (n, a), n.Distinct(name), a.Distinct(a.age));
S>

В ФП все такие операции делаются через fold/reduce (Aggregate в .Net).
Тот же самый Distinct выражется через Aggregate вот таким образом:
public IEnumerable<T> Distinct<T>(this IEnumerable<T> source) => 
  source.Aggregate(new ImmutableHashSet<T>(), (set, x) => set.Add(x));

То есть начинаем с пустого множества, а затем каждый из элементов исходной коллекции складываем в это множество (игнорируя дубликаты).
С учётом этого знания, решение от IT выглядит очевидным обобщением:
(names, ages) 
  = persons.Aggregate(
    (names: new ImmutableHasSet<string>(), ages:new ImmutableHashSet<int>()), 
    (acc, person) =>(acc.names.Add(person.name), acc.ages.Add(person.age))
  );