Как получить первый элемент из IEnumerable < > в .net?

Это могло бы сделать это:

function parseItem (item) {
  const [, stringPart = '', numberPart = 0] = /(^[a-zA-Z]*)(\d*)$/.exec(item) || [];
  return [stringPart, numberPart];
}

function sort (array) {
  return array.sort((a, b) => {
    const [stringA, numberA] = parseItem(a);
    const [stringB, numberB] = parseItem(b);
    const comparison = stringA.localeCompare(stringB);
    return comparison === 0 ? Number(numberA) - Number(numberB) : comparison;
  });
}

console.log(sort(['A1', 'A10', 'A11', 'A12', 'A2', 'A3', 'A4', 'B10', 'B2', 'F1', 'F12', 'F3']))

139
задан Amy B 30 January 2009 в 21:17
поделиться

5 ответов

Если можно использовать LINQ, можно использовать:

var e = enumerable.First();

Это выдаст исключение, хотя, если счетный пусто: в этом случае можно использовать:

var e = enumerable.FirstOrDefault();

FirstOrDefault() возвратится default(T), если счетное будет пусто, который будет null для ссылочных типов или 'нулевого значения' по умолчанию для типов значения.

, Если Вы не можете использовать LINQ, затем Ваш подход технически корректен и не отличается, чем создание перечислителя с помощью GetEnumerator, и MoveNext методы для получения первого результата (этот пример принимает счетный, IEnumerable<Elem>):

Elem e = myDefault;
using (IEnumerator<Elem> enumer = enumerable.GetEnumerator()) {
    if (enumer.MoveNext()) e = enumer.Current;
}

Joel Coehoorn упомянул .Single() в комментариях; это будет также работать, если Вы будете ожидать, что Ваше счетное будет содержать точно один элемент, то - однако он выдаст исключение, если это будет или пустым или больше, чем один элемент. Существует соответствие SingleOrDefault() метод, который касается этого сценария подобным способом к [1 111]. Однако David B объясняет, что SingleOrDefault() может все еще выдать исключение в случае, где счетное содержит больше чем один объект.

Редактирование: Спасибо Marc Gravell для указания, что я должен избавиться от моего IEnumerator объект после использования его - я отредактировал non-LINQ пример для отображения using ключевое слово для реализации этого шаблона.

219
ответ дан Community 31 January 2009 в 07:17
поделиться

На всякий случай Вы используете.NET 2.0 и не имеете доступа к LINQ:

 static T First<T>(IEnumerable<T> items)
 {
     using(IEnumerator<T> iter = items.GetEnumerator())
     {
         iter.MoveNext();
         return iter.Current;
     }
 }

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

Вызов это как так:

List<string> items = new List<string>() { "A", "B", "C", "D", "E" };
string firstItem = First<string>(items);

Или

int[] items = new int[] { 1, 2, 3, 4, 5 };
int firstItem = First<int>(items);

Вы могли изменить его с готовностью достаточно для имитации.NET 3.5's IEnumerable. ElementAt () дополнительный метод:

static T ElementAt<T>(IEnumerable<T> items, int index)
{
    using(IEnumerator<T> iter = items.GetEnumerator())
    {
        for (int i = 0; i <= index; i++, iter.MoveNext()) ;
        return iter.Current;
    }
} 

Вызов его как так:

int[] items = { 1, 2, 3, 4, 5 };
int elemIdx = 3;
int item = ElementAt<int>(items, elemIdx);

, Конечно, если Вы делаете , имеют доступ к LINQ, затем уже существует много хороших ответов, отправленных...

34
ответ дан BenAlabaster 31 January 2009 в 07:17
поделиться

Ну, Вы не указывали, какую версию .NET Вы используете.

Принятие Вы имеете 3.5, иначе метод ElementAt:

var e = enumerable.ElementAt(0);
24
ответ дан Adam Lassek 31 January 2009 в 07:17
поделиться

FirstOrDefault?

Elem e = enumerable.FirstOrDefault();
//do something with e
6
ответ дан Amy B 31 January 2009 в 07:17
поделиться

Используйте FirstOrDefault или цикл foreach, как уже упомянуто. Вручную выборки перечислителя и вызова Текущего нужно избежать. foreach расположит Ваш перечислитель для Вас, если он реализует IDisposable. При вызове MoveNext и Текущий необходимо расположить его вручную (если применимый).

0
ответ дан Mouk 31 January 2009 в 07:17
поделиться