Проверьте, все ли элементы списка имеют одинаковое значение члена в C#
Я ищу простой и быстрый способ проверить, все ли элементы списка имеют одинаковое значение для члена.
foreach (Item item in MyList)
{
Item.MyMember = <like all other>;
}
РЕДАКТИРОВАТЬ: я забыл одну вещь: если один из этих членов (его строка) является String.Empty и все другие элементы имеют одинаковую строку, это должно быть тоже верно! Извините, я забыл это.
5 ответов
РЕДАКТИРОВАТЬ: Хорошо, после того, как новое требование
bool allSame = !MyList.Select(item => item.MyMember)
.Where(x => !string.IsNullOrEmpty(x))
.Distinct()
.Skip(1)
.Any();
Это избавляет вас от необходимости делать первый шаг, чтобы найти одно значение выборки для начала. (И он все равно выйдет, как только найдет второе значение, конечно.)
Он также выполняет итерации последовательности только один раз, что может быть важно, если это не действительно повторяемая последовательность. Не проблема, если это List<T>
конечно.
РЕДАКТИРОВАТЬ: чтобы смягчить озабоченность по поводу Skip
из документации:
Если источник содержит меньше, чем количество элементов, пустой
IEnumerable<T>
возвращается Если число меньше или равно нулю, все элементы источника будут получены.
Ваше собственное решение уже достаточно просто, но если вы хотите абстрагироваться от цикла и написать его более выразительно, вы можете использовать Linq.
bool allSame = MyList.All(item => item.MyMember == someValue);
using System.Linq;
…
if (myList.Any()) // we need to distinguish between empty and non-empty lists
{
var value = myList.First().MyMember;
return myList.All(item => item.MyMember == value);
}
else
{
return true; // or false, if that is more appropriate for an empty list
}
Вот общий, который работает для всех версий.NET, начиная с 2.0:
public static bool AllSameByProperty<TItem, TProperty>(IEnumerable<TItem> items, Converter<TItem, TProperty> converter)
{
TProperty value = default(TProperty);
bool first = true;
foreach (TItem item in items)
{
if (first)
{
value = converter.Invoke(item);
first = false;
continue;
}
TProperty newValue = converter.Invoke(item);
if(value == null)
{
if(newValue != null)
{
return false;
}
continue;
}
if (!value.Equals(newValue))
{
return false;
}
}
return true;
}
Его использование в C# 2.0:
AllSameByProperty(list, delegate(MyType t) { return t.MyProperty; });
Его использование в C# 3.0:
AllSameByProperty(list, t => t.MyProperty);
Я делаю так:
Item item = MyList.FirstOrDefault(x=>x.MyMember != valueToMatch);
bool allMembersSame = item == null;
Думаю, это самое короткое и элегантное решение:
bool allSame = list.GroupBy(item => item.TheProperty).Count == 1;