সি # তে অ্যারে তুলনা করার সবচেয়ে সহজ উপায়


180

জাভাতে, Arrays.equals()দুটি বুনিয়াদি অ্যারের সামগ্রীগুলি সহজেই তুলনা করতে দেয় (ওভারলোডগুলি সমস্ত মৌলিক ধরণের জন্য উপলব্ধ)।

সি # তে কি এমন জিনিস আছে? সি # তে দুটি অ্যারের সামগ্রীর তুলনা করার কোনও "যাদু" উপায় আছে কি?


1
ট্যাগগুলিতে '.net' যুক্ত করা হয়েছে কারণ এই কৌশলটি অন্যান্য অনুরূপ। নেট ভিত্তিক ভাষায় ব্যবহৃত হতে পারে।
ইভান প্লেইস

3
এটি পড়া প্রত্যেকের জন্য, মনে রাখবেন যে গৃহীত উত্তরটি সিকোয়েন্সএকুয়াল ব্যবহার করছে is সিকোয়েন্সএকুয়াল কেবল একই ডেটা ধারণ করে তা পরীক্ষা করে না, একই সাথে একই ক্রমে একই তথ্য রাখে
জন ডেমেট্রিও

উত্তর:


262

আপনি ব্যবহার করতে পারে Enumerable.SequenceEqual। এটি IEnumerable<T>কেবল অ্যারে নয়, কোনওর জন্য কাজ করে।


এটি কেবল তখনই কাজ করে যদি তারা একই ক্রমে থাকে তবে
জন দেমেট্রিও

1
SequenceEqualপছন্দমত পারফরম্যান্সের ভিত্তিতে ভাল নাও হতে পারে, কারণ এটির বাস্তবায়ন কেবল দৈর্ঘ্য অনুসারে পৃথক হলে এর উত্সগুলির মধ্যে একটির সম্পূর্ণরূপে গণনা করতে পারে। অ্যারে সহ, আমরা Lengthপ্রথমে সমতা পরীক্ষা করতে পারতাম , কেবলমাত্র শেষ-ফলন প্রাপ্তির জন্য বিভিন্ন দৈর্ঘ্যের অ্যারেগুলি গণনা এড়াতে false
ফ্রিডরিক

72

ব্যবহার করুন Enumerable.SequenceEqualমধ্যে LINQ

int[] arr1 = new int[] { 1,2,3};
int[] arr2 = new int[] { 3,2,1 };

Console.WriteLine(arr1.SequenceEqual(arr2)); // false
Console.WriteLine(arr1.Reverse().SequenceEqual(arr2)); // true

1
মনে রাখবেন যে এটি নাল যুক্তিগুলির জন্য ছুড়ে ফেলেছে, সুতরাং এটি ধরে নেওয়ার বিষয়টি নিশ্চিত করুনnew int[] {1}.SequenceEquals(null) == false
sara

30

এছাড়াও অ্যারে (এবং টিপলস) এর জন্য আপনি .NET 4.0: IStructuralComparable এবং IStructuralEquatable থেকে নতুন ইন্টারফেস ব্যবহার করতে পারেন । এগুলি ব্যবহার করে আপনি কেবল অ্যারের সমতা পরীক্ষা করতে পারবেন না তবে তাদের তুলনাও করতে পারেন।

static class StructuralExtensions
{
    public static bool StructuralEquals<T>(this T a, T b)
        where T : IStructuralEquatable
    {
        return a.Equals(b, StructuralComparisons.StructuralEqualityComparer);
    }

    public static int StructuralCompare<T>(this T a, T b)
        where T : IStructuralComparable
    {
        return a.CompareTo(b, StructuralComparisons.StructuralComparer);
    }
}

{
    var a = new[] { 1, 2, 3 };
    var b = new[] { 1, 2, 3 };
    Console.WriteLine(a.Equals(b)); // False
    Console.WriteLine(a.StructuralEquals(b)); // True
}
{
    var a = new[] { 1, 3, 3 };
    var b = new[] { 1, 2, 3 };
    Console.WriteLine(a.StructuralCompare(b)); // 1
}

আমাকে ক্ষমা করুন, এটি 1 বা 0 ইন হওয়া উচিত a.StructuralCompare(b)?
মাফু

বৃহত মান ধরণের অ্যারেগুলিতে এগুলি ব্যবহার করে একটি পারফরম্যান্স হিট হয়, কারণ তাদের বর্তমান বাস্তবায়ন প্রতিটি মানকে তুলনা করার জন্য বক্স করবে।
ফ্রেডেরিক

18

জন্য .NET 4.0 এবং উচ্চতর আপনি ব্যবহার মাধ্যমে অ্যারের মধ্যে উপাদান অথবা tuples তুলনা করতে পারবেন StructuralComparisons টাইপ:

object[] a1 = { "string", 123, true };
object[] a2 = { "string", 123, true };

Console.WriteLine (a1 == a2);        // False (because arrays is reference types)
Console.WriteLine (a1.Equals (a2));  // False (because arrays is reference types)

IStructuralEquatable se1 = a1;
//Next returns True
Console.WriteLine (se1.Equals (a2, StructuralComparisons.StructuralEqualityComparer)); 

সম্পাদনা: খুব শিগগিরই কথা বলেছেন। আমি কি স্ট্রাকচারালএকুয়ালিটি ইস্টস্ট্রাকচারালকম্পেবলের সাথে তুলনা করতে পারি? কোনটি "প্রথমে" আসে তা জানতে আমি দুটি বস্তুর অ্যারে দিয়ে কম্পেরিটোকে কল করতে চাই। আমি চেষ্টা করেছি IStructuralComparable se1 = a1; কনসোল.উরাইটলাইন (se1.CompareTo (a2, স্ট্রাকচারালকম্পারিসনস। স্ট্রাকচারালএকুয়ালিটি কমপায়ার)); প্রাপ্তি: 'সিস্টেম.কলেশনস.আইক্যালিটিকম্পারার' থেকে '
সিস্টেম.কলেশনস.কম্পিয়ারার

1
ঠিক আছে - সঠিক কলটি হল: IStructuralComparable se1 = a1; কনসোল.উরাইটলাইন (se1.CompareTo (a2, স্ট্রাকচারালকম্পারিসনস। স্ট্রাকচারালকম্পার));
shindigo

15

SequenceEqual শুধুমাত্র দুটি শর্ত পূরণ বা পূরণ হলে সত্য ফিরে আসবে।

  1. এগুলিতে একই উপাদান রয়েছে।
  2. উপাদানগুলি একই ক্রমে থাকে।

যদি আপনি কেবল তাদের অর্ডার নির্বিশেষে একই উপাদানগুলিতে রয়েছে কিনা তা পরীক্ষা করতে চান এবং আপনার সমস্যাটি ধরণের

ভ্যালু 2 এ মান 1 এর মধ্যে থাকা সমস্ত মান রয়েছে?

আপনি লিনকিউ এক্সটেনশন পদ্ধতিটি ব্যবহার করতে পারেন Enumerable.Exceptএবং তারপরে ফলাফলটির কোনও মান আছে কিনা তা পরীক্ষা করতে পারেন। এখানে একটি উদাহরণ

int[] values1 = { 1, 2, 3, 4 };
int[] values2 = { 1, 2, 5 };
var result = values1.Except(values2);
if(result.Count()==0)
{
   //They are the same
}
else
{
    //They are different
}

এবং এটি ব্যবহার করে আপনি স্বয়ংক্রিয়ভাবে বিভিন্ন আইটেম পাবেন। এক ঢিলে দুই পাখি।

মনে রাখবেন, আপনি যদি নিজের কোডটি এভাবে চালিত করেন

var result = values2.Except(values1);

আপনি বিভিন্ন ফলাফল পাবেন।

আমার ক্ষেত্রে আমার কাছে একটি অ্যারের স্থানীয় অনুলিপি রয়েছে এবং এটি পরীক্ষা করতে চাই যে মূল অ্যারে থেকে কিছু সরানো হয়েছে কিনা তাই আমি এই পদ্ধতিটি ব্যবহার করি।


2
বিভিন্ন ক্রমে একই মানযুক্ত অ্যারেগুলি কেবল সমান নয়। আপনি কি 'ডিমেট্রিও' == 'uoirtemeD'?
edc65

সেটা নির্ভর করে. আপনি যদি অ্যারেগুলি বিনা নিয়ন্ত্রিত সংগ্রহ হিসাবে ব্যবহার করছেন এবং কেবলমাত্র তাদের একই উপাদান (যেমন, কোনও কনফিগার তালিকার বিপরীতে একটি ডেটাবেস থেকে মানগুলি) রয়েছে তা পরীক্ষা করে দেখার প্রয়োজন হয়, তবে এটি খুঁজে পাওয়া সবচেয়ে সহজ উপায়। যদি অর্ডারে কিছু আসে না (যেমন, একটি স্ট্রিং), তবে আপনি ব্যবহার করবেন SequenceEqual
আরমান্ডো

11

ইউনিট পরীক্ষার জন্য, আপনি এর CollectionAssert.AreEqualপরিবর্তে ব্যবহার করতে পারেন Assert.AreEqual

এটি সম্ভবত সবচেয়ে সহজ উপায়।


11

আপনি যদি nullইনপুটগুলি কৌতূহলীভাবে পরিচালনা করতে এবং আইটেমগুলির ক্রমটিকে উপেক্ষা করতে চান তবে নীচের সমাধানটি চেষ্টা করুন:

static class Extensions
{
    public static bool ItemsEqual<TSource>(this TSource[] array1, TSource[] array2)
    {
        if (array1 == null && array2 == null)
            return true;
        if (array1 == null || array2 == null)
            return false;
        return array1.Count() == array2.Count() && !array1.Except(array2).Any();
    }
}

পরীক্ষার কোডটি দেখে মনে হচ্ছে:

class Program
{
    static void Main(string[] args)
    {
        int[] a1 = new int[] { 1, 2, 3 };
        int[] a2 = new int[] { 3, 2, 1 };
        int[] a3 = new int[] { 1, 3 };
        int[] a4 = null;
        int[] a5 = null;
        int[] a6 = new int[0];

        Console.WriteLine(a1.ItemsEqual(a2)); // Output: True.
        Console.WriteLine(a2.ItemsEqual(a3)); // Output: False.
        Console.WriteLine(a4.ItemsEqual(a5)); // Output: True. No Exception.
        Console.WriteLine(a4.ItemsEqual(a3)); // Output: False. No Exception.
        Console.WriteLine(a5.ItemsEqual(a6)); // Output: False. No Exception.
    }
}

এটি আমার জন্য সহায়ক ছিল, তবে যদি a1 = { 1, 1 }এবং a2 = { 1, 2 }তবে প্রথম পরীক্ষায় ভুল ফলাফল ফিরে আসে। রিটার্নের স্টেটমেন্টটি হওয়া উচিতreturn array1.Count() == array2.Count() && !array1.Except(array2).Any() && !array2.Except(array1).Any();
পোলিশগিয়ান্ট

2

কিছু অ্যাপ্লিকেশন জন্য ভাল হতে পারে:

string.Join(",", arr1) == string.Join(",", arr2)

2

এই লিনকিউ সমাধানটি কাজ করে, নিশ্চিত না যে এটি সিকোয়েন্সএকুয়ালসের সাথে পারফরম্যান্সে কীভাবে তুলনা করে। তবে এটি বিভিন্ন অ্যারে দৈর্ঘ্য পরিচালনা করে এবং সমস্ত প্রথম অ্যারেতে প্রস্থান করবে যা পুরো অ্যারের মাধ্যমে পুনরাবৃত্তি না করে সমান নয়।

private static bool arraysEqual<T>(IList<T> arr1, IList<T> arr2)
        =>
            ReferenceEquals(arr1, arr2) || (
                arr1 != null && arr2 != null &&
                arr1.Count == arr2.Count &&
                arr1.Select((a, i) => arr2[i].Equals(a)).All(i => i)
            );

1

উপাদান হিসাবে তুলনা? কি সম্পর্কে

public void Linq78a()
{
 int[] numbers1 = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
 int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
 bool bb = numbers.Zip(numbers1, (a, b) => (a == b)).Any(p => !p);
 if (!bb) Console.WriteLine("Lists are equal (bb)");
   else Console.WriteLine("Lists are not equal (bb)");
}

আপনি a এবং b এর সাথে তুলনা করতে চান এমন কোনও কিছু দ্বারা (a == খ) শর্তটি প্রতিস্থাপন করুন।

(এটি এমএসডিএন বিকাশকারী লিনক নমুনার দুটি উদাহরণকে একত্রিত করে )


1
এটি বিভিন্ন দৈর্ঘ্যের অ্যারে পরিচালনা করে না (ভুলভাবে উত্পন্ন হতে পারে true) এবং nullঅ্যারেগুলি (ক্রাশ হবে)।
ফ্রিডরিক

1

আমি ভিজ্যুয়াল স্টুডিওগুলিতে এটি করেছি এবং এটি পুরোপুরি কাজ করেছে; সংক্ষিপ্ত এই কোডের সাথে সূচী দ্বারা অ্যারে সূচকগুলির তুলনা করা।

private void compareButton_Click(object sender, EventArgs e)
        {
            int[] answer = { 1, 3, 4, 6, 8, 9, 5, 4, 0, 6 };
            int[] exam = { 1, 2, 3, 6, 8, 9, 5, 4, 0, 7 };

            int correctAnswers = 0;
            int wrongAnswers = 0;

            for (int index = 0; index < answer.Length; index++)
            {
                if (answer[index] == exam[index])
                {
                    correctAnswers += 1;
                }
                else
                {
                    wrongAnswers += 1;
                }
            }

            outputLabel.Text = ("The matching numbers are " + correctAnswers +
                "\n" + "The non matching numbers are " + wrongAnswers);
        }

আউটপুট হবে; মিলের সংখ্যাগুলি 7 হ'ল মেলানো নম্বরগুলি 3


2
এটি বিভিন্ন দৈর্ঘ্যের অ্যারে পরিচালনা করবে না (ক্রাশ হবে), nullঅ্যারেগুলি (ক্র্যাশও হবে) এবং ওপি যা চেয়েছিল তা বাদ দিয়ে এটি অন্য কিছু করে। তিনি কেবলমাত্র সমতা জানতে চেয়েছিলেন, কত আইটেমের পার্থক্য বা মিল আছে তা গণনা ছাড়াই।
ফ্রিডরিক

0

অ্যারে সমতা ধরে নেওয়া মানে উভয় অ্যারে সমান সূচকগুলিতে সমান উপাদান রয়েছে, SequenceEqualউত্তর এবং IStructuralEquatableউত্তর আছে

তবে উভয়েরই ত্রুটি রয়েছে, পারফরম্যান্স বুদ্ধিমান।

SequenceEqual অ্যারেগুলির বিভিন্ন দৈর্ঘ্য থাকলে বর্তমান বাস্তবায়ন শর্টকাট হবে না এবং তাই এর প্রতিটি উপাদানের তুলনা করে এটির মধ্যে একটির সম্পূর্ণরূপে অঙ্ক করা যেতে পারে।

IStructuralEquatableজেনেরিক নয় এবং প্রতিটি তুলনামূলক মানের বক্সিংয়ের কারণ হতে পারে। তদুপরি এটি ব্যবহার করা খুব সহজ নয় এবং ইতিমধ্যে কিছু সহায়ক পদ্ধতি কোডিংয়ের জন্য এটি লুকিয়ে রাখার জন্য কল করে।

এর মতো কিছু ব্যবহার করা আরও ভাল, পারফরম্যান্স বুদ্ধিমান হতে পারে:

bool ArrayEquals<T>(T[] first, T[] second)
{
    if (first == second)
        return true;
    if (first == null || second == null)
        return false;
    if (first.Length != second.Length)
        return false;
    for (var i = 0; i < first.Length; i++)
    {
        if (first[i] != second[i])
            return false;
    }
    return true;
}

তবে অবশ্যই এটি অ্যারে সাম্যতা যাচাইয়ের কিছু "ম্যাজিক উপায়" নয়।

সুতরাং বর্তমানে, না, Arrays.equals()জাট। নেট এ আসলেই একটি সমতুল্য নেই ।


প্রথম এবং দ্বিতীয় উভয়ই কি সত্যই নালার ফলাফল হবে না? নাল == নাল, তাই না?
জেসি উইলিয়ামস

1
উভয় হলেই প্রথম পরীক্ষা সত্য হবে null। তোমার যুক্তি কী?
ফ্রেডেরিক

1
যদি (প্রথম [i]! = দ্বিতীয় [i]) জেনেরিকের সাথে কাজ করে না। আপনার অবশ্যই ব্যবহার করা উচিত (! প্রথম [i]। সমীকরণ (দ্বিতীয় [i]))।
জ্যাক গ্রিফিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.