C # Linq SortedList Фильтрация в SortedList - PullRequest
5 голосов
/ 24 марта 2011

У меня есть некоторый код, в котором я делаю некоторые странности, чтобы вытащить информацию из SortedList и обратно в другой SortedList. Я делаю свое предложение where, затем должен по отдельности поместить все KeyValuePairs обратно в новый SortedList.

Этот не может быть наиболее эффективным или действительно рекомендуемым способом сделать это, но я не могу найти лучшего способа.

Вот код:

SortedList<DateTime, CalendarDay> most_days = 
                                new SortedList<DateTime, CalendarDay>();
List<KeyValuePair<DateTime, CalendarDay>> days = this.all_days.Where (
                                  n => n.Value.IsRequested || n.Value.IsApproved
                                  ).ToList();
foreach (KeyValuePair<DateTime, CalendarDay> kvp in days)
    most_days.Add(kvp.Key, kvp.Value);

Любые идеи о том, как я могу это убрать (как говорится, чем меньше, тем лучше)?

Спасибо

Jonathan

Ответы [ 2 ]

9 голосов
/ 24 марта 2011

Ну, конечно, вы можете удалить звонок ToList - это вам совсем не поможет.

Вы можете сделать вызывающий код проще, как это:

var dictionary = allDays.Where(n => n.Value.IsRequested || n.Value.IsApproved)
                        .ToDictionary(x => x.Key, x => x.Value);
var mostDays = new SortedList<DateTime, CalendarDay>(dictionary);

... но это будет промежуточное звено Dictionary<,>, так что оно вряд ли будет эффективным.

Другой вариант заключается в том, что вы можете написать свой собственный метод расширения ToSortedList, например

public static SortedList<TKey, TValue> ToSortedList<TSource, TKey, TValue>
    (this IEnumerable<TSource> source,
     Func<TSource, TKey> keySelector,
     Func<TSource, TValue> valueSelector)
{
    // TODO: Argument validation
    var ret = new SortedList<TKey, TValue>();
    foreach (var element in source)
    {
        ret.Add(keySelector(element), valueSelector(element));
    }
    return ret;
}

Тогда код вызова будет просто:

var mostDays = allDays.Where(n => n.Value.IsRequested || n.Value.IsApproved)
                      .ToSortedList(x => x.Key, x => x.Value);

Я подозреваю, что это должно быть достаточно эффективно, так как оно всегда будет добавлять значения в конец списка 1018 * во время построения.

(Для полной работы вы хотели бы добавить перегрузки, принимающие пользовательские сравнения ключей и т. Д., См. ToDictionary.)

2 голосов
/ 24 марта 2011

Не прямой ответ на ваш вопрос (извините!) - больше вопрос по вопросу:

  • Вам действительно нужно, чтобы результат был SortedList?
  • Или вы можете выжить с выводом IEnumerable, где результаты оказываются в правильном порядке?

Если вы никогда не собираетесь добавлять / вставлять больше элементов в коллекцию mostDays после того, как вы 'Если бы вы создали его, то, очевидно, вы могли бы просто создать IEnumerable, используя var mostDays = allDays.Where(n => n.Value.IsRequested || n.Value.IsApproved);

...