Расположение XElement при запросе через IEnumerable с использованием LINQ

У меня есть запрос linq, который запрашивает IEnumberable. Когда у меня есть соответствующий элемент для моего предложения where, я хотел бы знать позицию элемента в IEnumerable.

var result = from e in elements
             where (string) e.Attribute("class") == "something"
             select e.Position();

e.Position(), конечно, не компилируется. Значением e.Position() будет позиция выбранного элемента в элементах IEnumerable.

Есть идеи, как это сделать?


person Joel Cunningham    schedule 21.02.2010    source источник


Ответы (2)


Вам необходимо использовать перегруженный метод Select, который позволяет использовать индекс, поскольку эта возможность недоступна в синтаксисе запроса.

elements.Select((e, i) => new { Element = e, Index = i })
        .Where(item => (string)item.Element.Attribute("class") == "something")
        .Select(item => item.Index);
person Ahmad Mageed    schedule 21.02.2010

Если вы используете .NET 4.0, вы можете использовать (новый) метод Zip и написать то же самое, используя синтаксис запроса. Он создает некоторые временные объекты, поэтому он не так эффективен, но некоторым людям он может показаться более читаемым:

var result = from e in elements.Zip
               (Enumerable.Range(0, elements.Count()), Tuple.Create) 
             where (string)e.Item1.Attribute("class") == "something" 
             select e.Item2; 

Он «сжимает» входную коллекцию сгенерированной последовательностью чисел (с тем же диапазоном, что и длина коллекции). Затем вы можете сохранить комбинированное значение либо с помощью класса Tuple (это то, что я сделал), либо вы можете использовать анонимный тип.

person Tomas Petricek    schedule 21.02.2010