Выберите элемент по индексу из .NET HashSet

В настоящее время я использую собственный класс, полученный из HashSet. Там пункт в коде, когда я выбираю элементы при определенных условиях:

var c = clusters.Where(x => x.Label != null && x.Label.Equals(someLabel));

Он отлично работает, и я получаю эти элементы. Но есть ли способ получить индекс этого элемента внутри коллекции для использования с методом ElementAt вместо целых объектов?

Это выглядело бы примерно так:

var c = select element index in collection under certain condition;
int index = c.ElementAt(0); //get first index
clusters.ElementAt(index).RunObjectMthod();

Является ли ручная повторная обработка всей коллекции лучше? Мне нужно добавить, что это в большем цикле, поэтому это предложение Where выполняется несколько раз для разных строк someLabel.

Edit

Для чего мне это нужно? clusters представляет собой набор кластеров некоторого набора документов. Документы сгруппированы в кластеры по сходству тем. Таким образом, одним из последних шагов алгоритма является обнаружение метки для каждого кластера. Но алгоритм не совершенен, и иногда он создает два или более кластера с одной и той же меткой. Я хочу просто слить этот кластер в большой.

Ответ 1

У наборов обычно нет индексов. Если для вас важна позиция, вы должны использовать List<T> вместо (или, возможно, так же, как) набор.

Теперь SortedSet<T> в .NET 4 несколько отличается тем, что поддерживает упорядоченный порядок значений. Однако он все еще не реализует IList<T>, поэтому доступ по индексу с ElementAt будет медленным.

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

Ответ 2

В случае, когда вы храните элементы в HashSet, и иногда вам нужно получить элементы по индексу, рассмотрите возможность использования метода расширения ToList() в таких ситуациях. Таким образом, вы используете функции HashSet, а затем используете индексы.

HashSet<T> hashset = new HashSet<T>();

//the special situation where we need index way of getting elements
List<T> list = hashset.ToList();

//doing our special job, for example mapping the elements to EF entities collection (that was my case)

//we can still operate on hashset for example when we still want to keep uniqueness through the elements 

Ответ 3

Нет такой вещи, как индекс с хэш-множеством. Один из способов, которым хеш-наборы в некоторых случаях эффективны, заключается в том, что они не должны поддерживать их.

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

Если вы хотите сделать несколько операций над одним и тем же объектом, просто держитесь за этот объект.

Если вы хотите что-то сделать на нескольких объектах, сделайте это на основе итерации через них (обычный foreach или сделайте foreach по результатам Where() и т.д.). Если вы хотите что-то сделать на нескольких объектах, а затем сделать что-то еще на этих нескольких объектах, и вам нужно сделать это в таких партиях, вместо того чтобы выполнять все операции в одном и том же foreach, затем сохранить результаты Where() в List<T>.