सभी सूची आइटम समान मान होने पर उसे कैसे चेक करें और उसे वापस करें, या यदि वे नहीं करते हैं तो "otherValue" लौटाएं?


122

यदि किसी सूची में सभी वस्तुओं का समान मूल्य है, तो मुझे उस मूल्य का उपयोग करने की आवश्यकता है, अन्यथा मुझे "अन्यवैल्यू" का उपयोग करने की आवश्यकता है। मैं ऐसा करने का एक सरल और स्पष्ट तरीका नहीं सोच सकता।

लूप लिखने के लिए नीट तरीका भी देखें, जिसमें किसी संग्रह में पहले आइटम के लिए विशेष तर्क है।


आपके बजाय गंदे ध्यान देने वाले पर, मैं Ani के जवाब के साथ जाऊंगा। stackoverflow.com/questions/4390232/…
बाइनरी वॉरियर

5
सूची खाली होने के कारण पहला मूल्य नहीं होने पर आप क्या करना चाहते हैं? उस स्थिति में यह सच है कि "सूची में सभी वस्तुओं का मूल्य समान है" - यदि आप मुझ पर विश्वास नहीं करते हैं, तो मुझे एक खोजें जो नहीं है! आप इस स्थिति में क्या करना है परिभाषित नहीं करते हैं। क्या यह एक अपवाद फेंकना चाहिए, "अन्य" मान लौटाएं, या क्या?
एरिक लिपपर्ट

@ एरिक, क्षमा करें जब सूची खाली है तो उसे "अन्य" मान वापस करना चाहिए
इयान रिंगरोज

जवाबों:


153
var val = yyy.First().Value;
return yyy.All(x=>x.Value == val) ? val : otherValue; 

सबसे साफ तरीका मैं सोच सकता हूं। आप इसे वैलिंग इनलाइन करके वन-लाइनर बना सकते हैं, लेकिन पहले () का मूल्यांकन n समय, दोहरीकरण निष्पादन समय से किया जाएगा।

टिप्पणियों में निर्दिष्ट "खाली सेट" व्यवहार को शामिल करने के लिए, आप बस ऊपर दो से पहले एक और पंक्ति जोड़ेंगे:

if(yyy == null || !yyy.Any()) return otherValue;

1
+1, क्या .Anyउन गणनाओं के लिए अनुमति देता है जो उन मामलों में जल्दी छोड़ सकती हैं जहां विभिन्न मूल्य हैं?
जेफ ओगाटा

12
@adrift: Allजैसे ही यह xअनुक्रम का एक तत्व हिट करता है, समाप्त हो जाएगा x.Value != val। इसी तरह, Any(x => x.Value != val)जैसे ही यह xअनुक्रम के एक तत्व को हिट करता है , समाप्त हो जाएगा x.Value != val। यही है, दोनों Allऔर Any"लघु-परिशोधन" के अनुरूप ( &&और ||प्रभावी रूप से जो हैं Allऔर Anyहैं) प्रदर्शित करते हैं।
जेसन

@ जेसन: बिल्कुल। सभी (स्थिति) प्रभावी रूप से है! कोई भी (स्थिति), और उत्तर के ज्ञात होते ही या तो मूल्यांकन समाप्त हो जाएगा।
कीथ्स

4
माइक्रोपोप्टिसिमेशन:return yyy.Skip(1).All(x=>x.Value == val) ? val : otherValue;
कैल्टर

100

सभी के लिए अच्छा त्वरित परीक्षण:

collection.Distinct().Count() == 1

1
यह सिर्फ किसी के साथ काम नहीं करेगा Class, हालांकि इसे स्ट्रक्चर्स के साथ काम करना चाहिए। यद्यपि आदिमों की सूची के लिए महान।
एंड्रयू बैकर

2
कीथ के समाधान IMO की तुलना में बहुत अधिक स्वच्छ। collection.Distinct().Count() <= 1 यदि आप खाली संग्रह की अनुमति देना चाहते हैं, तो आप इसका उपयोग कर सकते हैं।
डी ग्रैबर

4
सावधान रहें, .Distinct()हमेशा अपेक्षित रूप से काम नहीं करता है - खासकर जब आप वस्तुओं के साथ काम करते हैं, तो यह प्रश्न देखें । उस स्थिति में, आपको IEquatable इंटरफ़ेस को लागू करने की आवश्यकता है।
मैट

16
औसत मामले में क्लीनर, हाँ, लेकिन कम प्रदर्शन करने वाला; डिस्टिक्ट () को संग्रह में हर एक तत्व को एक बार पार करने की गारंटी है, और हर तत्व के अलग-अलग होने की स्थिति में, काउंट () पूरी सूची को दो बार पार करेगा। डिस्टिक्ट () भी एक HashSet बनाता है ताकि इसका व्यवहार रैखिक हो और NlogN या इससे भी बदतर न हो, और यह मेमोरी के उपयोग को बढ़ावा देगा। सभी () सभी तत्वों के सबसे खराब स्थिति में एक पूर्ण पास बनाता है, और कोई नया संग्रह नहीं बनाता है।
21

1
@KeithS जैसा कि मुझे उम्मीद है कि अब तक आपको पता चल गया है, Distinctइस संग्रह को बिल्कुल भी पीछे नहीं छोड़ा जाएगा, और Countएक यात्रा के माध्यम से एक यात्रा करना होगा Distinct
22

22

यद्यपि आप निश्चित रूप से मौजूदा अनुक्रम ऑपरेटरों से इस तरह के एक उपकरण का निर्माण कर सकते हैं, मैं इस मामले में एक कस्टम अनुक्रम ऑपरेटर के रूप में इसे लिखना चाहूंगा। कुछ इस तरह:

// 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)या कुछ ऐसे हस्ताक्षर थे, जो इसे थोड़ा जटिल करते हैं।
एंथनी पेग्राम

@ एंथनी: दरअसल, यहां कई जटिलताएं हैं, लेकिन वे बहुत आसानी से चारों ओर काम कर रहे हैं। मैं एक सुविधा के रूप में एक अशक्त int का उपयोग कर रहा हूं ताकि मुझे "पहले आइटम को पहले ही देखा है" झंडा घोषित करने की आवश्यकता न हो। आप आसानी से सिर्फ झंडे की घोषणा कर सकते थे। इसके अलावा, मैं T के बजाय "int" का उपयोग कर रहा हूं क्योंकि मुझे पता है कि आप हमेशा समानता के लिए दो ints की तुलना कर सकते हैं, जो कि दो Ts के लिए नहीं है। यह पूरी तरह कार्यात्मक जेनेरिक समाधान की तुलना में समाधान का एक स्केच है।
एरिक लिपर्ट

13
return collection.All(i => i == collection.First())) 
    ? collection.First() : otherValue;.

या यदि आप प्रत्येक तत्व के लिए पहले () निष्पादित करने के बारे में चिंतित हैं (जो एक वैध प्रदर्शन चिंता हो सकती है):

var first = collection.First();
return collection.All(i => i == first) ? first : otherValue;

@KeithS - जिसके कारण मैंने अपने उत्तर का दूसरा भाग जोड़ा। छोटे संग्रह पर, कॉलिंग फर्स्ट () तुच्छ है। बड़े संग्रह पर, यह एक मुद्दा बनना शुरू हो सकता है।
जस्टिन निस्नेर

1
"छोटे संग्रह पर, कॉलिंग फर्स्ट () तुच्छ है।" - यह संग्रह के स्रोत पर निर्भर करता है। साधारण वस्तुओं की सूची या सरणी के लिए, आप बिल्कुल सही हैं। लेकिन, कुछ enumerables प्राइमेट के मेमोरी-कैश्ड सेट नहीं हैं। प्रतिनिधियों का एक संग्रह, या एक एन्यूमरेटर जो एक एल्गोरिथम श्रृंखला गणना (जैसे फाइबोनैचि) के माध्यम से उपज देता है, हर बार पहले () का मूल्यांकन करने के लिए बहुत महंगा होगा।
कीथ्स

5
या इससे भी बदतर, अगर क्वेरी डेटाबेस क्वेरी है और "फर्स्ट" कॉलिंग डेटाबेस को हर बार फिर से हिट करता है।
एरिक लिपिपर्ट

1
यह तब और खराब हो जाता है जब आपके पास एक बार की पुनरावृत्ति होती है जैसे फ़ाइल से पढ़ना ... इसलिए अन्य थ्रेड से एनी का उत्तर सबसे अच्छा लगता है।
अलेक्सई लेवेनकोव

@ ईरिक - C'mon। प्रत्येक तत्व के लिए डेटाबेस को तीन बार मारने के साथ कुछ भी गलत नहीं है ...:
--P

3

यह देर हो सकती है, लेकिन एक विस्तार जो एरिक के जवाब के आधार पर एक जैसे मूल्य और संदर्भ प्रकारों के लिए काम करता है:

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;
    }
}

1
public int GetResult(List<int> list){
int first = list.First();
return list.All(x => x == first) ? first : SOME_OTHER_VALUE;
}

1

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;

सबसे पहले यह बहुत सारा कचरा पैदा कर सकता है। इसके अलावा यह कम स्पष्ट है तो अन्य LINQ उत्तर, लेकिन धीमी तो विस्तार विधि जवाब।
इयान रिंगरोज 14

सच। हालांकि, अगर हम यह निर्धारित करने के बारे में बात कर रहे हैं कि क्या बहुत अधिक कचरा नहीं होगा, तो क्या मानों का एक छोटा समूह सभी समान हैं। जब मैंने इसे और LINQPad में मानों के एक छोटे से सेट के लिए एक LINQ बयान चलाया, तो HashSet तेज था (स्टॉपवॉच वर्ग का उपयोग करके समयबद्ध)।
Ɖयमोंड ƦeezeƦ

यदि आप इसे कमांड लाइन से रिलीज़ बिल्ड में चलाते हैं तो आपको अलग परिणाम मिल सकते हैं।
इयान रिंगरोज

एक सांत्वना अनुप्रयोग बनाया और पाया कि HashSet<T>शुरू में मेरे उत्तर में LINQ बयानों का उपयोग करने की तुलना में तेज है। हालांकि, अगर मैं इसे लूप में करता हूं, तो LINQ तेज है।
Ɖiamond ǤeezeƦ

बड़ा इस समाधान के साथ मुद्दा यह है कि आप अपने कस्टम कक्षाओं उपयोग कर रहे हैं, आप अपने खुद को लागू करना है GetHashCode(): है, जो सही ढंग से करने के लिए देखें मुश्किल है stackoverflow.com/a/371348/2607840 अधिक जानकारी के लिए।
कैमरून

0

उपरोक्त सरलीकृत दृष्टिकोण पर थोड़ा बदलाव।

var result = yyy.Distinct().Count() == yyy.Count();


3
यह बिल्कुल दूसरे तरीके का दौर है। यह जाँच करेगा कि सूची में प्रत्येक तत्व अद्वितीय है।
मारियो गैलिया

-1

अगर कोई एरे नीचे की तरह मल्टीमिडिशन का है तो हमें डेटा की जांच करने के लिए लिनेक के नीचे लिखना होगा।

उदाहरण: यहाँ तत्व 0 हैं और मैं जाँच रहा हूँ सभी मान 0 या नहीं हैं।
ip1 =
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";   
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.