সি # তে একটি ফরইচ স্টেটমেন্ট সহ দুটি তালিকাগুলি বা অ্যারেগুলি পরিবেশন করুন


142

এটি কেবল সাধারণ জ্ঞানের জন্য:

যদি আমার দুটি থাকে তবে আসুন, তালিকাটি বলুন এবং আমি একই ফোরচ লুপ দিয়ে উভয়কে পুনরাবৃত্তি করতে চাই, আমরা কি এটি করতে পারি?

সম্পাদন করা

কেবল পরিষ্কার করতে, আমি এটি করতে চেয়েছিলাম:

List<String> listA = new List<string> { "string", "string" };
List<String> listB = new List<string> { "string", "string" };

for(int i = 0; i < listA.Count; i++)
    listB[i] = listA[i];

তবে একটি পূর্বসূরীর সাথে =)


10
এখানে গুরুত্বপূর্ণ শব্দটি হল "জিপ"।
মার্ক বাইয়ার্স

3
আপনি কি সমান্তরালভাবে দুটি তালিকা পুনরাবৃত্তি করতে চান ? অথবা আপনি কি প্রথমে একটি তালিকা পুনরাবৃত্তি করতে চান এবং তারপরে অন্যটি (একক বিবৃতি দিয়ে)?
পাভেল মিনায়েভ

আমি মনে করি আপনার
আলেকজান্ডার

উত্তর:


274

এটি জিপ অপারেশন হিসাবে পরিচিত এবং। নেট 4 এ সমর্থিত হবে।

এটির সাহায্যে আপনি এমন কিছু লিখতে সক্ষম হবেন:

var numbers = new [] { 1, 2, 3, 4 };
var words = new [] { "one", "two", "three", "four" };

var numbersAndWords = numbers.Zip(words, (n, w) => new { Number = n, Word = w });
foreach(var nw in numbersAndWords)
{
    Console.WriteLine(nw.Number + nw.Word);
}

নামযুক্ত ক্ষেত্রগুলির সাথে বেনামে টাইপের বিকল্প হিসাবে, আপনি একটি টিপল এবং এর স্থির Tuple ব্যবহার করে ধনুর্বন্ধনীতেও সংরক্ষণ করতে পারেন re

foreach (var nw in numbers.Zip(words, Tuple.Create)) 
{
    Console.WriteLine(nw.Item1 + nw.Item2);
}


2
এই জিপ অপারেশনগুলি সম্পর্কে কিছুই জানতেন না, আমি সেই বিষয়ে একটি ছোট গবেষণা করব। ধন্যবাদ!
হুগো

4
@ হুগো: এটি ফাংশনাল প্রোগ্রামিংয়ে একটি স্ট্যান্ডার্ড কনস্ট্রাক্ট :)
মার্ক সিম্যান

আপনাকে সিস্টেম.লিনক ব্যবহার করতে হবে;
জাহেমিক

5
সি # 7 সাল থেকে, এছাড়াও আপনি একটি ValueTuple (দেখুন ব্যবহার করতে পারে stackoverflow.com/a/45617748 ) পরিবর্তে বেনামী ধরনের বা Tuple.Create। অর্থাৎ foreach ((var number, var word) in numbers.Zip(words, (n, w) => (n, w))) { ... }
এরলেন্ড গ্রাফ

14

আপনি .NET 4.0 এর জন্য অপেক্ষা করতে না চাইলে আপনি নিজের Zipপদ্ধতি প্রয়োগ করতে পারেন । নিম্নলিখিত .NET 2.0 সঙ্গে কাজ করে। আপনি যেখানে দুটি বর্ণ (বা তালিকা) পৃথক দৈর্ঘ্যের ক্ষেত্রে কেস পরিচালনা করতে চান তার উপর নির্ভর করে আপনি বাস্তবায়নটি সামঞ্জস্য করতে পারেন; এটি স্বল্পতর গণনা থেকে হারিয়ে যাওয়া আইটেমগুলির জন্য ডিফল্ট মানগুলি প্রত্যাবর্তন করে দীর্ঘতর গণনার শেষে অবিরত থাকবে।

static IEnumerable<KeyValuePair<T, U>> Zip<T, U>(IEnumerable<T> first, IEnumerable<U> second)
{
    IEnumerator<T> firstEnumerator = first.GetEnumerator();
    IEnumerator<U> secondEnumerator = second.GetEnumerator();

    while (firstEnumerator.MoveNext())
    {
        if (secondEnumerator.MoveNext())
        {
            yield return new KeyValuePair<T, U>(firstEnumerator.Current, secondEnumerator.Current);
        }
        else
        {
            yield return new KeyValuePair<T, U>(firstEnumerator.Current, default(U));
        }
    }
    while (secondEnumerator.MoveNext())
    {
        yield return new KeyValuePair<T, U>(default(T), secondEnumerator.Current);
    }
}

static void Test()
{
    IList<string> names = new string[] { "one", "two", "three" };
    IList<int> ids = new int[] { 1, 2, 3, 4 };

    foreach (KeyValuePair<string, int> keyValuePair in ParallelEnumerate(names, ids))
    {
        Console.WriteLine(keyValuePair.Key ?? "<null>" + " - " + keyValuePair.Value.ToString());
    }
}

1
দুর্দান্ত পদ্ধতি! :)। আপনি .NET 4 জিপ পদ্ধতি হিসাবে একই স্বাক্ষর ব্যবহার করার জন্য একটি কয়েক সমন্বয় করতে পারেন msdn.microsoft.com/en-us/library/dd267698.aspx এবং বিনিময়ে resultSelector (প্রথম, দ্বিতীয়) পরিবর্তে একটি KVP।
মার্টন কল

নোট করুন যে এই পদ্ধতিটি তার গণককে নিষ্পত্তি করে না যা কোনও সমস্যা হয়ে উঠতে পারে, উদাহরণস্বরূপ যদি এটি খোলার ফাইলগুলির লাইনে গণনার সাথে ব্যবহৃত হয়।
Lii

11

আপনি ইউনিয়ন বা কনক্যাট ব্যবহার করতে পারবেন, প্রাক্তনগুলি সদৃশগুলি সরিয়ে ফেলবে, পরে তা করবে না

foreach (var item in List1.Union(List1))
{
   //TODO: Real code goes here
}

foreach (var item in List1.Concat(List1))
{
   //TODO: Real code goes here
}

ইউনিয়ন ব্যবহারের সাথে আর একটি সমস্যা হ'ল এটি সমান হিসাবে মূল্যায়ন করলে উদাহরণগুলি ফেলে দিতে পারে। এটি সর্বদা আপনি যা চান তা নাও হতে পারে।
স্যামন

1
আমি
দৃ tough়

@ মার্ক সিমেন, আমি ইতিমধ্যে চিহ্নিত করেছি যে, তিনি কনক্যাট
আলবার্টেইন

ইউনিয়নের মতো, কনক্যাট কেবল তখনই কাজ করে যদি দুটি তালিকা একই ধরণের হয়। যদিও
ওপিটির এটির

এটি একটি নতুন তালিকা তৈরি করে যাতে সমস্ত উপাদান রয়েছে। এটি স্মৃতির অপচয়। পরিবর্তে লিনক কনক্যাট ব্যবহার করুন।
ড্রয় নোকস

3

এখানে একটি কাস্টম আইনিউমেবল <> এক্সটেনশন পদ্ধতি যা একসাথে দুটি তালিকার মাধ্যমে লুপ করতে ব্যবহৃত হতে পারে।

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    public static class LinqCombinedSort
    {
        public static void Test()
        {
            var a = new[] {'a', 'b', 'c', 'd', 'e', 'f'};
            var b = new[] {3, 2, 1, 6, 5, 4};

            var sorted = from ab in a.Combine(b)
                         orderby ab.Second
                         select ab.First;

            foreach(char c in sorted)
            {
                Console.WriteLine(c);
            }
        }

        public static IEnumerable<Pair<TFirst, TSecond>> Combine<TFirst, TSecond>(this IEnumerable<TFirst> s1, IEnumerable<TSecond> s2)
        {
            using (var e1 = s1.GetEnumerator())
            using (var e2 = s2.GetEnumerator())
            {
                while (e1.MoveNext() && e2.MoveNext())
                {
                    yield return new Pair<TFirst, TSecond>(e1.Current, e2.Current);
                }
            }

        }


    }
    public class Pair<TFirst, TSecond>
    {
        private readonly TFirst _first;
        private readonly TSecond _second;
        private int _hashCode;

        public Pair(TFirst first, TSecond second)
        {
            _first = first;
            _second = second;
        }

        public TFirst First
        {
            get
            {
                return _first;
            }
        }

        public TSecond Second
        {
            get
            {
                return _second;
            }
        }

        public override int GetHashCode()
        {
            if (_hashCode == 0)
            {
                _hashCode = (ReferenceEquals(_first, null) ? 213 : _first.GetHashCode())*37 +
                            (ReferenceEquals(_second, null) ? 213 : _second.GetHashCode());
            }
            return _hashCode;
        }

        public override bool Equals(object obj)
        {
            var other = obj as Pair<TFirst, TSecond>;
            if (other == null)
            {
                return false;
            }
            return Equals(_first, other._first) && Equals(_second, other._second);
        }
    }

}

3

সি # 7 যেহেতু আপনি টিপলস ব্যবহার করতে পারেন ...

int[] nums = { 1, 2, 3, 4 };
string[] words = { "one", "two", "three", "four" };

foreach (var tuple in nums.Zip(words, (x, y) => (x, y)))
{
    Console.WriteLine($"{tuple.Item1}: {tuple.Item2}");
}

// or...
foreach (var tuple in nums.Zip(words, (x, y) => (Num: x, Word: y)))
{
    Console.WriteLine($"{tuple.Num}: {tuple.Word}");
}

1
এই পরিস্থিতিতে যখন দুটি তালিকা একই দৈর্ঘ্য নয় তখন কী হবে?
জন আগস্ট

সঙ্গে (x, y) => (x, y)আমরা নামে ব্যবহার করতে পারেন tuple.xএবং tuple.yমার্জিত পারে। সুতরাং দ্বিতীয় (Num, Word) => (Num, Word)
ফর্মটিও

2
@ জোহান অগাস্ট এটি সংক্ষিপ্ত ক্রমটি অনুসরণ করার পরে শেষ হয়। ডক্স থেকে: "যদি সিকোয়েন্সগুলিতে একই সংখ্যক উপাদান থাকে না তবে পদ্ধতিটি ক্রমের একত্রিত হয় যতক্ষণ না এটি একটির শেষের দিকে পৌঁছে যায় example উদাহরণস্বরূপ, যদি একটি অনুক্রমের তিনটি উপাদান থাকে এবং অন্যটিতে চারটি থাকে, ফলাফল ক্রমটি হবে মাত্র তিনটি উপাদান রয়েছে "
গ্রেগস্মি

0

না, আপনাকে এটির জন্য একটি লুপ ব্যবহার করতে হবে।

for (int i = 0; i < lst1.Count; i++)
{
    //lst1[i]...
    //lst2[i]...
}

আপনি এর মতো কিছু করতে পারবেন না

foreach (var objCurrent1 int lst1, var objCurrent2 in lst2)
{
    //...
}

তাদের আলাদা আলাদা গণনা থাকলে কী হবে?
ড্রয় নোকস

তারপরে একটি ভবিষ্যদ্বাণী যা গণনার একটি স্বেচ্ছাসেবী তালিকা গ্রহণ করবে তা কাজ করবে না, এভাবে পুরো জিনিসটিকে অকেজো করে।
ম্যাক্সিমিলিয়ান মেয়ারেল

0

যদি আপনি সংশ্লিষ্ট উপাদানগুলির সাথে একটি উপাদান চান তবে আপনি করতে পারেন

Enumerable.Range(0, List1.Count).All(x => List1[x] == List2[x]);

যদি প্রতিটি আইটেম দ্বিতীয় তালিকার সংশ্লিষ্টগুলির সাথে সমান হয় তবে এটি সত্য হবে

যদি এটি প্রায় তবে আপনি যা চান তা পুরোপুরি না হলে আপনি আরও বিশদ বিবরণী দিলে এটি সহায়তা করবে।


0

এই পদ্ধতিটি তালিকা প্রয়োগের জন্য কাজ করবে এবং এটি একটি এক্সটেনশন পদ্ধতি হিসাবে প্রয়োগ করা যেতে পারে।

public void TestMethod()
{
    var first = new List<int> {1, 2, 3, 4, 5};
    var second = new List<string> {"One", "Two", "Three", "Four", "Five"};

    foreach(var value in this.Zip(first, second, (x, y) => new {Number = x, Text = y}))
    {
        Console.WriteLine("{0} - {1}",value.Number, value.Text);
    }
}

public IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(List<TFirst> first, List<TSecond> second, Func<TFirst, TSecond, TResult> selector)
{
    if (first.Count != second.Count)
        throw new Exception();  

    for(var i = 0; i < first.Count; i++)
    {
        yield return selector.Invoke(first[i], second[i]);
    }
}

0

তালিকাগুলির একই দৈর্ঘ্য থাকলে আপনি কেবল একটি স্থানীয় পূর্ণসংখ্য পরিবর্তনশীল ব্যবহার করতে পারেন:

List<classA> listA = fillListA();
List<classB> listB = fillListB();

var i = 0;
foreach(var itemA in listA)
{
    Console.WriteLine(itemA  + listB[i++]);
}

-1

আপনি নিম্নলিখিতগুলি করতে পারেন:

var i = 0;
foreach (var itemA in listA)
{
  Console.WriteLine(itemA + listB[i++]);
}

দ্রষ্টব্য: দৈর্ঘ্য listAঅবশ্যই এর সাথে একই হবে listB


-3

আমি বুঝতে / আশা করি যে তালিকাগুলির একই দৈর্ঘ্য রয়েছে: না, আপনার একমাত্র বাজি লুপের জন্য একটি সাধারণ পুরানো মান নিয়ে চলেছে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.