リスト内のすべての項目に同じ値がある場合は、その値を使用する必要があります。それ以外の場合は、「otherValue」を使用する必要があります。これを行うための簡単で明確な方法は考えられません。
リスト内のすべての項目に同じ値がある場合は、その値を使用する必要があります。それ以外の場合は、「otherValue」を使用する必要があります。これを行うための簡単で明確な方法は考えられません。
回答:
var val = yyy.First().Value;
return yyy.All(x=>x.Value == val) ? val : otherValue;
私が考えることができる最もきれいな方法。valをインライン化することで1行にすることができますが、First()はn回評価され、実行時間が2倍になります。
コメントで指定された「空のセット」の動作を組み込むには、上記の2つの前に1行追加するだけです。
if(yyy == null || !yyy.Any()) return otherValue;
.Any
異なる値がある場合に列挙を早期に終了するためにallowを使用しますか?
All
要素x
にヒットするとすぐに終了しx.Value != val
ます。同様に、シーケンスのAny(x => x.Value != val)
要素x
にヒットするとすぐに終了しx.Value != val
ます。つまり、両方All
とAny
展示「短絡」に類似&&
して||
(事実上何であるAll
とAny
されています)。
return yyy.Skip(1).All(x=>x.Value == val) ? val : otherValue;
すべてが等しい場合の迅速なテスト:
collection.Distinct().Count() == 1
Class
structでは機能しますが、だけでは機能しません。ただし、プリミティブのリストには最適です。
collection.Distinct().Count() <= 1
空のコレクションを許可する場合は、使用 することをお勧めします。
Distinct
が、コレクションをまったく走査しません。Count
Distinct
の反復子を介して1回走査します。
このようなデバイスを既存のシーケンスオペレーターから構築することは確かに可能ですが、この場合は、カスタムシーケンスオペレーターとしてこれを作成する傾向があります。何かのようなもの:
// Returns "other" if the list is empty.
// Returns "other" if the list is non-empty and there are two different elements.
// Returns the element of the list if it is non-empty and all elements are the same.
public static int Unanimous(this IEnumerable<int> sequence, int other)
{
int? first = null;
foreach(var item in sequence)
{
if (first == null)
first = item;
else if (first.Value != item)
return other;
}
return first ?? other;
}
これはかなり明確で短く、すべてのケースをカバーし、シーケンスの余分な反復を不必要に作成しません。
これを機能するジェネリックメソッドにすることIEnumerable<T>
は、演習として残します。:-)
other
ときにを返しnull
ます。関数がT Unanimous<U, T>(this IEnumerable<U> sequence, T other)
そのようなシグネチャであったとすると、少し複雑になります。
return collection.All(i => i == collection.First()))
? collection.First() : otherValue;.
または、各要素に対してFirst()を実行することを心配している場合(これは有効なパフォーマンスの問題になる可能性があります):
var first = collection.First();
return collection.All(i => i == first) ? first : otherValue;
これは遅いかもしれませんが、Ericの回答に基づいて、値と参照のタイプに同様に機能する拡張機能:
public static partial class Extensions
{
public static Nullable<T> Unanimous<T>(this IEnumerable<Nullable<T>> sequence, Nullable<T> other, IEqualityComparer comparer = null) where T : struct, IComparable
{
object first = null;
foreach(var item in sequence)
{
if (first == null)
first = item;
else if (comparer != null && !comparer.Equals(first, item))
return other;
else if (!first.Equals(item))
return other;
}
return (Nullable<T>)first ?? other;
}
public static T Unanimous<T>(this IEnumerable<T> sequence, T other, IEqualityComparer comparer = null) where T : class, IComparable
{
object first = null;
foreach(var item in sequence)
{
if (first == null)
first = item;
else if (comparer != null && !comparer.Equals(first, item))
return other;
else if (!first.Equals(item))
return other;
}
return (T)first ?? other;
}
}
LINQを使用する代わりの方法:
var set = new HashSet<int>(values);
return (1 == set.Count) ? values.First() : otherValue;
私はHashSet<T>
、最大で6,000までの整数のリストを使用する方が、
var value1 = items.First();
return values.All(v => v == value1) ? value1: otherValue;
HashSet<T>
が私の答えでLINQステートメントを使用するよりも最初に速いことがわかりました。ただし、これをループで実行すると、LINQの方が速くなります。
GetHashCode()
これを正しく行うのは困難です。詳細については、stackoverflow.com / a / 371348/2607840を参照してください。
配列が以下のような多次元型の場合、データをチェックするためにlinqの下に書き込む必要があります。
例:ここでは要素は0で、すべての値が0かどうかを確認しています。
ip1 =
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
var value=ip1[0][0]; //got the first index value
var equalValue = ip1.Any(x=>x.Any(xy=>xy.Equals())); //check with all elements value
if(equalValue)//returns true or false
{
return "Same Numbers";
}else{
return "Different Numbers";
}