Можно ли в качестве keySelector при вызове IEnumerable.OrderBy использовать недетерминированную функцию, т.е. такую, которая не обязательно вернет один и тот же ключ, будучи вызвана дважды для одного элемента?
С одной стороны, то, что OrderBy вычисляет и кеширует ключи элементов перед сортировкой — это вроде деталь реализации, но с другой — в документации к OrderBy на keySelector не налагается никаких требований, кроме того чтобы для возвращаемых значений ключа существовал Comparer<TKey>.Default.
Здравствуйте, i1yich, Вы писали:
I>Можно ли в качестве keySelector при вызове IEnumerable.OrderBy использовать недетерминированную функцию, т.е. такую, которая не обязательно вернет один и тот же ключ, будучи вызвана дважды для одного элемента?
I>С одной стороны, то, что OrderBy вычисляет и кеширует ключи элементов перед сортировкой — это вроде деталь реализации, но с другой — в документации к OrderBy на keySelector не налагается никаких требований, кроме того чтобы для возвращаемых значений ключа существовал Comparer<TKey>.Default.
Я к чему спрашиваю, вот например в задаче, когда нужно перечислить последовательность в случайном порядке, если полагаться на кеширование ключей, код будет выглядеть достаточно просто:
public static IEnumerable<T> RandomOrder<T>(this IEnumerable<T> source)
{
var rnd = new Random();
return source.OrderBy(_ => rnd.Next());
}
Если же "ключ" элемента равный rnd.Next, будет вычисляться при каждом сравнении, то некоторые алгоритмы сортировки могут и не закончиться за предсказуемое время!
Здравствуйте, i1yich, Вы писали:
I>>Можно ли в качестве keySelector при вызове IEnumerable.OrderBy использовать недетерминированную функцию, т.е. такую, которая не обязательно вернет один и тот же ключ, будучи вызвана дважды для одного элемента?
I>>С одной стороны, то, что OrderBy вычисляет и кеширует ключи элементов перед сортировкой — это вроде деталь реализации, но с другой — в документации к OrderBy на keySelector не налагается никаких требований, кроме того чтобы для возвращаемых значений ключа существовал Comparer<TKey>.Default.
I>Я к чему спрашиваю, вот например в задаче, когда нужно перечислить последовательность в случайном порядке, если полагаться на кеширование ключей, код будет выглядеть достаточно просто:
Порассуждайте сами: OrderBy вычитывает переданную последовательность в буфер, сортирует и возвращает. По другому она в принципе не может работать. Зачем вам использовать её для перемешивания элементов и задаваться непонятными вопросами, когда вам достаточно так же сомому вычитать последовательность с буфер, перемешать и возвратить перемешанное, не бребегая к OrderBy вовсе?
Help will always be given at Hogwarts to those who ask for it.
I>Я к чему спрашиваю, вот например в задаче, когда нужно перечислить последовательность в случайном порядке, если полагаться на кеширование ключей, код будет выглядеть достаточно просто:
I>
I> public static IEnumerable<T> RandomOrder<T>(this IEnumerable<T> source)
I> {
I> var rnd = new Random();
I> return source.OrderBy(_ => rnd.Next());
I> }
I>
I>Если же "ключ" элемента равный rnd.Next, будет вычисляться при каждом сравнении, то некоторые алгоритмы сортировки могут и не закончиться за предсказуемое время!
_FR>Порассуждайте сами: OrderBy вычитывает переданную последовательность в буфер, сортирует и возвращает. По другому она в принципе не может работать.
Есть и другие реализации LINQ, например LinqBridge. Там при сортировке keySelector выполняется для каждого сравнения (пока).
_FR>Зачем вам использовать её для перемешивания элементов и задаваться непонятными вопросами, когда вам достаточно так же сомому вычитать последовательность с буфер, перемешать и возвратить перемешанное, не бребегая к OrderBy вовсе?
Здесь вы правы, для перемешивания действительно лучше использовать алгоритм перемешивания.
Здравствуйте, i1yich, Вы писали:
_FR>>Порассуждайте сами: OrderBy вычитывает переданную последовательность в буфер, сортирует и возвращает. По другому она в принципе не может работать. I>Есть и другие реализации LINQ, например LinqBridge. Там при сортировке keySelector выполняется для каждого сравнения (пока).
В данном случае важно только в точности то, что я написал: "OrderBy вычитывает переданную последовательность в буфер, сортирует и возвращает".
_FR>>Зачем вам использовать её для перемешивания элементов и задаваться непонятными вопросами, когда вам достаточно так же сомому вычитать последовательность с буфер, перемешать и возвратить перемешанное, не бребегая к OrderBy вовсе? I>Здесь вы правы, для перемешивания действительно лучше использовать алгоритм перемешивания.
Суть не в "алгоритме перемешивания", а в том, что OrderBy вы используете не по назначению. Гораздо проще будет совсем обойтись без OrderBy и не забивать голову деталями её реализации.
Help will always be given at Hogwarts to those who ask for it.