หากรายการทั้งหมดในรายการมีค่าเท่ากันฉันจำเป็นต้องใช้ค่านั้นมิฉะนั้นฉันต้องใช้“ otherValue” ฉันไม่สามารถคิดวิธีที่ง่ายและชัดเจนในการทำเช่นนี้
ดูวิธีการเขียนลูปที่มีตรรกะพิเศษสำหรับรายการแรกในคอลเล็กชันด้วย
หากรายการทั้งหมดในรายการมีค่าเท่ากันฉันจำเป็นต้องใช้ค่านั้นมิฉะนั้นฉันต้องใช้“ otherValue” ฉันไม่สามารถคิดวิธีที่ง่ายและชัดเจนในการทำเช่นนี้
ดูวิธีการเขียนลูปที่มีตรรกะพิเศษสำหรับรายการแรกในคอลเล็กชันด้วย
คำตอบ:
var val = yyy.First().Value;
return yyy.All(x=>x.Value == val) ? val : otherValue;
วิธีที่สะอาดที่สุดที่ฉันคิดได้ คุณสามารถทำให้เป็นซับเดียวได้โดย inlining val แต่ First () จะได้รับการประเมิน n ครั้งโดยเพิ่มเวลาดำเนินการเป็นสองเท่า
หากต้องการรวมลักษณะการทำงาน "ชุดว่าง" ที่ระบุไว้ในความคิดเห็นคุณเพียงเพิ่มอีกหนึ่งบรรทัดก่อนหน้าสองข้อด้านบน:
if(yyy == null || !yyy.Any()) return otherValue;
.Any
อนุญาตให้การแจงนับเลิกก่อนในกรณีที่มีค่าต่างกันหรือไม่
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
แม้ว่ามันควรจะทำงานกับโครงสร้าง เหมาะสำหรับรายการดั้งเดิม
collection.Distinct().Count() <= 1
หากคุณต้องการอนุญาตคอลเลกชันที่ว่างเปล่า
Distinct
จะไม่ข้ามคอลเลกชันเลยและCount
จะทำการสำรวจผ่านทางDistinct
iterator ของ
แม้ว่าคุณจะสามารถสร้างอุปกรณ์ดังกล่าวจากตัวดำเนินการลำดับที่มีอยู่ได้อย่างแน่นอน แต่ในกรณีนี้ฉันก็อยากจะเขียนสิ่งนี้เป็นตัวดำเนินการลำดับที่กำหนดเอง สิ่งที่ต้องการ:
// 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;
}
}
public int GetResult(List<int> list){
int first = list.First();
return list.All(x => x == first) ? first : SOME_OTHER_VALUE;
}
ทางเลือกในการใช้ 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สำหรับรายละเอียดเพิ่มเติม
การเปลี่ยนแปลงเล็กน้อยในแนวทางที่เรียบง่ายข้างต้น
var result = yyy.Distinct().Count() == yyy.Count();
หากอาร์เรย์เป็นประเภทหลายมิติเช่นด้านล่างเราจะต้องเขียน linq ด้านล่างเพื่อตรวจสอบข้อมูล
ตัวอย่าง: องค์ประกอบที่นี่คือ 0 และฉันกำลังตรวจสอบค่าทั้งหมดว่าเป็น 0 หรือไม่
ip1 =
0 0 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";
}