Гарантия не менее одного в список


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

Цель: если есть какие-то элементы в списке, и никто из них не имеет данного свойства, установить одну из них, чтобы иметь это свойство.

static void GuaranteeAtLeastOne<T>(IEnumerable<T> list, Func<T,bool> getter, Action<T> setter)
{
    if (list.Any() && !list.Any(getter))
    {
        setter(list.First());
    }
}


833
3
задан 2 августа 2011 в 01:08 Источник Поделиться
Комментарии
3 ответа

Я бы не предположить, чтобы пойти в первый, а я бы Функ сказуемое параметр, который вы передаете на .Метода firstordefault(сказуемое) и ?? его .Во-первых()

Кроме того, я хотел проверить интерфейс IEnumerable != нуль, прежде чем что-либо.

static void GuaranteeAtLeastOne<T>(IEnumerable<T> list, Func<T,bool> getter, Action<T> setter, Func<T,bool> predicate)
{
if (list == null || list.Count == 0 || list.Any(getter))
{
return;
}

setter(list.FirstOrDefault(predicate) ?? list.First());
}

4
ответ дан 2 августа 2011 в 02:08 Источник Поделиться

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

bool hasItem = false;
T first = null; // or perhaps ... = default(T);

foreach (T item in list)
{
if (!hasItem)
{
hasItem = true;
first = item;
}

if (getter(item))
return;
}

if (hasItem)
{
setter(first);
}

Или используя перечислитель и без флага

using (var enumerator = list.GetEnumerator())
{
if (!enumerator.MoveNext())
return;

T first = enumerator.Current;

do
{
if (getter(enumerator.Current))
{
return;
}
} while (enumerator.MoveNext());

setter(first);
}

2
ответ дан 2 августа 2011 в 07:08 Источник Поделиться

Я бы отдельный метод в 3 отдельных частей:


  1. Заявление охранника, который проверяет, если список доступен

  2. Попробуйте найти элемент, который попадает в необходимое состояние

  3. Сеттер, наборы свойств reuiqred к элементу

В этом случае 2-й и 3-й части могут быть легко извлечены из метода и использовать повторно, если это необходимо.

static void GuaranteeAtLeastOne<T>(IEnumerable<T> list, Func<T,bool> getter, Action<T> setter)
{
if (list == null || !list.Any())
{
return;
}

T item = list.Where(getter).FirstOrDefault();

if (item != null)
{
return;
}

setter(list.First());
}

0
ответ дан 3 августа 2011 в 03:08 Источник Поделиться