লিনকিউ সমপরিমাণ <টি> এর জন্য পূর্ববর্তী অংশের সমান


716

আমি লিনকিউতে নিম্নলিখিতগুলির সমতুল্য কাজটি করতে চাই, তবে কীভাবে আমি তা বুঝতে পারি না:

IEnumerable<Item> items = GetItems();
items.ForEach(i => i.DoStuff());

আসল বাক্য গঠন কী?


99
এরিক লিপার্টের "ফরচ" বনাম "ফোরএচ" বিবেচনা করুন । এটা তোলে জন্য ভাল আত্মপক্ষ সমর্থন প্রদান করে না ব্যবহার / একটি সরবরাহ ForEach()

4
@ পিএসটি: আমি আমার প্রকল্পগুলিতে এই এক্সটেনশন পদ্ধতিগুলিকে অন্ধভাবে আটকে রেখেছি। নিবন্ধের জন্য ধন্যবাদ।
রবিন মাবেন

2
নেই MoreLINQ যা হয়েছে ForEachএক্সটেনশন
উয়ে কেইম

2
খুব সেক্সি না হলেও, এটি টোলিস্টের মাধ্যমে অনুলিপি তৈরি না করেই এক লাইনে ফিট করে -foreach (var i in items) i.Dostuff();
জেমস ওয়েস্টগেট

1
এর মধ্যে কিছু লিঙ্ক মারা গেছে! এত নিবন্ধটি কী ছিল যে এত বেশি ভোট হয়েছিল!
ওয়ারেন

উত্তর:


863

এর জন্য কোনও ফরইচ এক্সটেনশন নেই IEnumerable; শুধুমাত্র List<T>। সুতরাং আপনি করতে পারে

items.ToList().ForEach(i => i.DoStuff());

বিকল্পভাবে, আপনার নিজের forEach এক্সটেনশন পদ্ধতিটি লিখুন:

public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
    foreach(T item in enumeration)
    {
        action(item);
    }
}

213
টোলিস্ট () এর সাথে সাবধান থাকুন, কারণ টোললিস্ট () ক্রমটির একটি অনুলিপি তৈরি করে, যা কার্য সম্পাদন এবং মেমরির সমস্যার কারণ হতে পারে।
ডেসটেলজাউ

15
".Foreach ()" আরও ভাল হবে এর কয়েকটি কারণ রয়েছে। 1. মাল্টি-থ্রেডিং, পলিংক দ্বারা সম্ভব। ২. ব্যতিক্রম, আপনি লুপে সমস্ত ব্যতিক্রম সংগ্রহ করতে এবং এটি একবারে নিক্ষেপ করতে চাইতে পারেন; এবং এগুলি শোর কোড are
ডেনিস সি

12
পিনকিউ ফোরঅল নট ফরইচ ব্যবহার করে, এজন্য আপনি ফোরচেক ব্যবহার করবেন না।
ব্যবহারকারী 7116

9
IENumerable<T>আপনার এক্সটেনশন পদ্ধতিতে একটি ফিরিয়ে দেওয়া উচিত । পছন্দ:public static IEnumerable<T> ForAll<T>(this IEnumerable<T> numeration, Action<T> action) { foreach (T item in enumeration) { action(item); } return enumeration; }
কিস সি বাকার

22
নোট করুন যে প্রথম ক্ষেত্রে বিকাশকারী 1) প্রায় কোনও টাইপিং সংরক্ষণ করে না এবং 2) অকারণে পুরো ক্রমটি ফেলে দেওয়ার আগে তালিকাটিকে পুরো তালিকাটি সংরক্ষণ করার জন্য অযথা মেমরি বরাদ্দ করে। আপনার আগে লিনকিউ
সোউলকে

364

ফ্রেড্রিক ঠিকঠাক সরবরাহ করেছেন, তবে এটি কেন কাঠামোতে শুরু হচ্ছে না তা বিবেচনা করার মতো। আমি বিশ্বাস করি যে এই ধারণাটি এই যে লিনকিউ ক্যোয়ারী অপারেটরগুলি পার্শ্ব-প্রতিক্রিয়ামুক্ত হওয়া উচিত, বিশ্বের দিকে তাকানোর যুক্তিসঙ্গত কার্যকরী উপায়ে ফিট করা উচিত। স্পষ্টতই ফরইচ এর বিপরীত - খাঁটি পার্শ্ব-প্রতিক্রিয়া-ভিত্তিক নির্মাণ ruct

এটি করা খারাপ কাজ বলে তা নয় - কেবল সিদ্ধান্তের পিছনে দার্শনিক কারণ সম্পর্কে চিন্তা করা।


44
এবং এখনও, এফ # এর Seq.iter রয়েছে
স্টিফেন

6
তবে লিনক ফাংশনগুলি সাধারণত সেই ফোরচ () দেয় না এমন একটি খুব দরকারী জিনিস রয়েছে - লিনক ফাংশনগুলি দ্বারা গৃহীত বেনাম ফাংশন একটি প্যারামিটার হিসাবে একটি সূচকও নিতে পারে, তবে ফোরচের সাথে আপনাকে অবশ্যই ক্লাসিকটি পুনর্গঠন করতে হবে (ইন্ট আই ..) ) নির্মাণ। এবং কার্যকরী ভাষাগুলির পুনরাবৃত্তির পার্শ্ব প্রতিক্রিয়া থাকতে হবে - অন্যথায় আপনি তাদের সাথে কোনও কাজ কখনও করতে পারেন নি :) আমি উল্লেখ করতে চাই যে আদর্শিক কার্যকরী পদ্ধতিটি মূল সংখ্যাটি অপরিবর্তিত রেখে দেবে।
ওয়াল্ট ডাব্লু

3
@ ওয়াল্ট: আমি এখনও নিশ্চিত নই যে আমি সম্মত, আংশিক কারণ একটি সাধারণ সত্যিকারের কার্যকরী পদ্ধতির ফলে এই জাতীয় ভবিষ্যত ব্যবহার করা হবে না ... এটি লিনকিউয়ের মতো কার্যকরী পদ্ধতির ব্যবহার করবে, একটি নতুন ক্রম তৈরি করবে।
জন স্কেটি

12
@ স্টেফেন সোয়েনসেন: হ্যাঁ, এফ # এর সিক.আইটার রয়েছে, তবে এফ # এরও অপরিবর্তনীয় ডেটা কাঠামো রয়েছে। এগুলিতে Seq.iter ব্যবহার করার সময়, আসল সেকটি সংশোধন করা হয়নি; পার্শ্ব-প্রভাবিত উপাদানগুলির সাথে একটি নতুন সিক ফিরে আসে।
Anders

7
@ আন্ডারস - Seq.iterকিছু ফেরত দেবে না, পাশাপাশি পার্শ্ব-প্রভাবযুক্ত উপাদানগুলির সাথে একটি নতুন সিককে ছেড়ে দিন। এটি আসলে পার্শ্ব প্রতিক্রিয়া সম্পর্কে। আপনার চিন্তা করা যেতে পারে Seq.map, কারণ Seq.iterঅবিকল একটি সমতূল্য ForEachউপর এক্সটেনশন পদ্ধতি IEnumerabe<_>
জোয়েল মুয়েলার

39

আপডেট 7/17/2012: দৃশ্যত সি # 5.0 হিসাবে, foreachনীচে বর্ণিত আচরণগুলির পরিবর্তন করা হয়েছে এবং " একটি নেস্টেড ল্যাম্বডা এক্সপ্রেশনটিতে একটি foreachপুনরাবৃত্তির পরিবর্তনশীল ব্যবহার আর অপ্রত্যাশিত ফলাফল আনবে না " "এই উত্তরটি সি # ≥ 5.0 তে প্রযোজ্য নয় ।

@ জন স্কিটি এবং যারা ভবিষ্যদ্বাণী কীওয়ার্ডটি পছন্দ করেন তারা সবাই।

৫.০ এর পূর্বে সি # তে "ফোরচ" এর সমস্যাটি হ'ল এটি অন্যান্য ভাষায় "বোঝার জন্য" সমতুল্য কীভাবে কাজ করে এবং আমি কীভাবে এটি কাজ করতে পারি তার সাথে অসঙ্গতিপূর্ণ (ব্যক্তিগত মতামত কেবল এখানে বর্ণিত কারণ অন্যরা তাদের উল্লেখ করেছেন পঠনযোগ্যতা সম্পর্কিত মতামত)। " পরিবর্তিত ক্লোজারে অ্যাক্সেস " এবং " ক্ষতিকারক হিসাবে বিবেচিত লুপ ভেরিয়েবলটি বন্ধ করা" সম্পর্কিত সমস্ত প্রশ্ন দেখুন । এটি কেবলমাত্র "ক্ষতিকারক" কারণ সি # তে "ভবিষ্যদ্বাণী" প্রয়োগ করা হয়।

@ ফ্রেড্রিক কালসেথের উত্তরটিতে কার্যত সমমানের সম্প্রসারণ পদ্ধতিটি ব্যবহার করে নিম্নলিখিত উদাহরণগুলি নিন।

public static class Enumerables
{
    public static void ForEach<T>(this IEnumerable<T> @this, Action<T> action)
    {
        foreach (T item in @this)
        {
            action(item);
        }
    }
}

অত্যধিক স্বীকৃত উদাহরণের জন্য ক্ষমাপ্রার্থী। আমি কেবল পর্যবেক্ষণযোগ্য ব্যবহার করছি কারণ এটির মতো কিছু করার পক্ষে এটি পুরোপুরি খুব বেশি দূরে নেই। স্পষ্টতই এই পর্যবেক্ষণযোগ্য তৈরি করার আরও ভাল উপায় আছে, আমি কেবল একটি পয়েন্ট প্রদর্শন করার চেষ্টা করছি। সাধারণত পর্যবেক্ষণযোগ্য সদস্যতার জন্য সাবস্ক্রাইব করা কোডটি তাত্পর্যপূর্ণভাবে এবং সম্ভবত অন্য থ্রেডে কার্যকর করা হয়। যদি "ফরচ" ব্যবহার করা হয় তবে এটি খুব বিস্ময়কর এবং সম্ভাব্য অ-নির্জনবাদী ফলাফল আনতে পারে।

"ফরইচ" এক্সটেনশন পদ্ধতি ব্যবহার করে নিম্নলিখিত পরীক্ষাটি পাস করে:

[Test]
public void ForEachExtensionWin()
{
    //Yes, I know there is an Observable.Range.
    var values = Enumerable.Range(0, 10);

    var observable = Observable.Create<Func<int>>(source =>
                            {
                                values.ForEach(value => 
                                    source.OnNext(() => value));

                                source.OnCompleted();
                                return () => { };
                            });

    //Simulate subscribing and evaluating Funcs
    var evaluatedObservable = observable.ToEnumerable().Select(func => func()).ToList();

    //Win
    Assert.That(evaluatedObservable, 
        Is.EquivalentTo(values.ToList()));
}

নিম্নলিখিত ত্রুটিটি ব্যর্থ:

প্রত্যাশিত: <0, 1, 2, 3, 4, 5, 6, 7, 8, 9> এর সমান তবে এটি ছিল: <9, 9, 9, 9, 9, 9, 9, 9, 9, 9>

[Test]
public void ForEachKeywordFail()
{
    //Yes, I know there is an Observable.Range.
    var values = Enumerable.Range(0, 10);

    var observable = Observable.Create<Func<int>>(source =>
                            {
                                foreach (var value in values)
                                {
                                    //If you have resharper, notice the warning
                                    source.OnNext(() => value);
                                }
                                source.OnCompleted();
                                return () => { };
                            });

    //Simulate subscribing and evaluating Funcs
    var evaluatedObservable = observable.ToEnumerable().Select(func => func()).ToList();

    //Fail
    Assert.That(evaluatedObservable, 
        Is.EquivalentTo(values.ToList()));
}

রিশার্পার সতর্কতা কী বলে?
রেগেইগুইটার

1
@reggaeguitar আমি 7 বা 8 বছরে C # ব্যবহার করিনি, যেহেতু সি # 5.0 প্রকাশের আগে, যা এখানে বর্ণিত আচরণকে পরিবর্তন করেছে। সময়ে এটি এই সতর্কতাটি দিয়েছিল stackoverflow.com/questions/1688465/… । আমি সন্দেহ করি যে এটি এখনও এটি সম্পর্কে সতর্ক করে।
drstevens

34

আপনি FirstOrDefault()এক্সটেনশনটি ব্যবহার করতে পারেন , যা এর জন্য উপলব্ধ IEnumerable<T>falseশিকারী থেকে ফিরে , এটি প্রতিটি উপাদানের জন্য চালানো হবে তবে এটি কোনও মিল খুঁজে পাবে না সেদিকে খেয়াল রাখবে না। এটি ToList()ওভারহেড এড়াতে পারবে ।

IEnumerable<Item> items = GetItems();
items.FirstOrDefault(i => { i.DoStuff(); return false; });

11
আমিও একমত। এটি একটি চতুর সামান্য হ্যাক হতে পারে, তবে প্রথম দর্শনে, একটি স্ট্যান্ডার্ড ফোরচ লুপের তুলনায় অবশ্যই এই কোডটি এটি কী করছে তা স্পষ্ট নয়।
কনেল

26
আমি হ্রাস করতে হয়েছিল কারণ প্রযুক্তিগতভাবে সঠিক হওয়ার সময় , আপনার ভবিষ্যতের স্ব এবং আপনার উত্তরসূরিরা আপনাকে চিরদিনের জন্য ঘৃণা করবে কারণ foreach(Item i in GetItems()) { i.DoStuff();}আপনি তার পরিবর্তে আরও চরিত্র গ্রহণ করেছেন এবং এটি অত্যন্ত বিভ্রান্তিকর করেছেন
মার্ক সোওল

14
ঠিক আছে তবে items.All(i => { i.DoStuff(); return true; }
প্রলি

5
আমি জানি এটি মোটামুটি পুরানো পোস্ট, তবে আমার এটিও ডাউন ডাউন করতে হয়েছিল। আমি একমত যে এটি একটি চতুর কৌশল, কিন্তু এটি রক্ষণাবেক্ষণযোগ্য নয়। প্রথম নজরে দেখে মনে হচ্ছে এটি কেবল তালিকার প্রথম আইটেমটির সাথে কিছু করছে। কোডাররা এটি কীভাবে কাজ করে এবং এটি কী করছে বলে অনুমান করা হচ্ছে তা ভুল বোঝাবুঝির মাধ্যমে ভবিষ্যতে সহজেই আরও বাগ তৈরি করতে পারে।
লি

4
এটি পার্শ্ব প্রতিক্রিয়া প্রোগ্রামিং এবং আইএমএইচও নিরুত্সাহিত।
আনিস

21

আমি ফ্রেড্রিকের পদ্ধতি নিয়েছি এবং রিটার্নের ধরণটি সংশোধন করেছি।

এই পদ্ধতিটি, অন্যান্য লিনকিউ পদ্ধতির মতো স্থগিত কার্যকরকরণকে সমর্থন করে।

সম্পাদনা: এটি স্পষ্ট না হলে, এই পদ্ধতির যে কোনও ব্যবহার অবশ্যই টোললিস্ট () বা অন্য যে কোনও উপায়ে পদ্ধতিটিকে সম্পূর্ণ গণনাকারী হিসাবে কাজ করতে বাধ্য করতে হবে with অন্যথায়, কর্ম সম্পাদন করা হবে না!

public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
    foreach (T item in enumeration)
    {
        action(item);
        yield return item;
    }
}

এটি দেখার জন্য এখানে পরীক্ষার ব্যবস্থা রয়েছে:

[Test]
public void TestDefferedExecutionOfIEnumerableForEach()
{
    IEnumerable<char> enumerable = new[] {'a', 'b', 'c'};

    var sb = new StringBuilder();

    enumerable
        .ForEach(c => sb.Append("1"))
        .ForEach(c => sb.Append("2"))
        .ToList();

    Assert.That(sb.ToString(), Is.EqualTo("121212"));
}

যদি আপনি শেষ পর্যন্ত টোলিস্ট () সরিয়ে ফেলেন তবে আপনি পরীক্ষাটি ব্যর্থ দেখতে পাবেন যেহেতু স্ট্রিংবিল্ডারে একটি খালি স্ট্রিং রয়েছে। এটি কারণ কোনও পদ্ধতিই ফোরিচকে গণনা করতে বাধ্য করে না।


আপনার বিকল্প বাস্তবায়ন ForEachআকর্ষণীয়, তবে এটি এর আচরণের সাথে মেলে না List.ForEach, যার স্বাক্ষর public void ForEach(Action<T> action)। এটি Observable.ForEachএক্সটেনশনের আচরণের সাথেও মিলছে না IObservable<T>, যার স্বাক্ষর public static void ForEach<TSource>(this IObservable<TSource> source, Action<TSource> onNext)। এফডাব্লুআইডাব্লু, ForEachস্কালার সংগ্রহগুলির সমতুল্য, এমনকি অলস, এমনকি তাদের রিটার্ন টাইপও রয়েছে যা সি # তে শূন্যের সমান।
drstevens

এটি সেরা উত্তর: স্থগিত কার্যকরকরণ + সাবলীল এপিআই।
আলেকজান্ডার ড্যানিলভ

3
এটি কল করার Selectসাথে ঠিক একইভাবে কাজ করে ToList। এর উদ্দেশ্য ForEachহল কল না করা ToList। এটি অবিলম্বে কার্যকর করা উচিত।
t3chb0t

3
এই "ফরইচ", যার মৃত্যুদণ্ড স্থগিত, বনাম, যা তাত্ক্ষণিকভাবে কার্যকর করা হবে তাতে কী লাভ হবে? ডিফারিং (যা ফোরইচ কীভাবে ব্যবহার করা হবে তাতে অসুবিধে হয়) এই বিষয়টি কমিয়ে দেয় না যে ফোরইচ কেবলমাত্র কার্যকর কাজ সম্পাদন করে যদি অ্যাকশনটির পার্শ্ব প্রতিক্রিয়া থাকে [এই জাতীয় লিঙ্ক অপারেটরের বিরুদ্ধে করা স্বাভাবিক অভিযোগ]। সুতরাং, কিভাবে কাজ করে এই পরিবর্তন সাহায্য? তদতিরিক্ত, যুক্ত "ToList ()" এটিকে কার্যকর করতে বাধ্য করার জন্য, কোনও কার্যকর উদ্দেশ্য করে না। এটি ঘটতে অপেক্ষা করে দুর্ঘটনা। "ফরইচ" এর পয়েন্টটি এর পার্শ্ব প্রতিক্রিয়া। যদি আপনি কোনও ফেরত গণনা চান তবে নির্বাচন আরও বোধগম্য।
স্টিভ

20

আপনার পার্শ্ব প্রতিক্রিয়াগুলি আমার আইনিউনামের বাইরে রাখুন

আমি লিনকিউতে নিম্নলিখিতগুলির সমতুল্য কাজটি করতে চাই, তবে কীভাবে আমি তা বুঝতে পারি না:

অন্যরা যেমন এখানে এবং বিদেশে লিনকিউ দেখিয়েছে এবং IEnumerableপদ্ধতিগুলি পার্শ্ব-প্রতিক্রিয়ামুক্ত থাকবে বলে আশা করা হচ্ছে।

আপনি কি আসলেই আইনেউমারেবলের প্রতিটি আইটেমটিতে "কিছু করতে" চান? তারপরে foreachসেরা পছন্দ। পার্শ্ব-প্রতিক্রিয়াগুলি এখানে ঘটলে লোকেরা অবাক হয় না।

foreach (var i in items) i.DoStuff();

আমি বাজি ধরছি আপনি কোনও পার্শ্ব-প্রতিক্রিয়া চান না

তবে আমার অভিজ্ঞতায় পার্শ্ব প্রতিক্রিয়াগুলি সাধারণত প্রয়োজন হয় না। প্রায়শই না সেক্ষেত্রে একটি সাধারণ লিনকিউ কোয়েরি রয়েছে যার সাহায্যে স্ট্যাকওভারফ্লো ডটকম উত্তরটি জোন স্কিট, এরিক লিপার্ট, বা মার্ক গ্র্যাভেল দ্বারা প্রকাশিত হয়েছে যা আপনি কী করতে চান তা ব্যাখ্যা করে!

কিছু উদাহরণ

যদি আপনি আসলে কিছু মান একত্রিত করে (জমে) থাকেন তবে আপনার Aggregateএক্সটেনশন পদ্ধতিটি বিবেচনা করা উচিত ।

items.Aggregate(initial, (acc, x) => ComputeAccumulatedValue(acc, x));

সম্ভবত আপনি IEnumerableবিদ্যমান মানগুলি থেকে একটি নতুন তৈরি করতে চান ।

items.Select(x => Transform(x));

অথবা হতে পারে আপনি একটি চেহারা সারণী তৈরি করতে চান:

items.ToLookup(x, x => GetTheKey(x))

সম্ভাব্যতার তালিকাটি (পুরোপুরি উদ্দেশ্যপ্রণোদিত নয়) চলছে এবং চলছে।


7
আহ, সুতরাং নির্বাচন মানচিত্র, এবং সমষ্টি হ্রাস হ্রাস।
ড্যারাল লি

17

আপনি যদি গণনা রোলস হিসাবে কাজ করতে চান তবে আপনার প্রতিটি আইটেম পাওয়া উচিত ।

public static class EnumerableExtensions
{
    public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
    {
        foreach (var item in enumeration)
        {
            action(item);
            yield return item;
        }
    }
}

আপনি যখন আইটেমটি ফিরিয়ে দেন এটি সত্যিই ফোরএচ নয়, এটি আরও বেশি একটি ট্যাপের মতো।
এলুসিয়াসএফটিডাব্লু

10

সেখানে Microsoft দ্বারা একটি পরীক্ষামূলক রিলিজ LINQ করার ইন্টারেক্টিভ এক্সটেনশানগুলি (এছাড়াও NuGet উপর দেখুন RxTeams এর প্রফাইল আরো লিঙ্ক জন্য)। চ্যানেল 9 ভিডিও এটা ভাল ব্যাখ্যা করে।

এর ডক্সটি কেবল এক্সএমএল ফর্ম্যাটে সরবরাহ করা হয়েছে। আমি এই ডকুমেন্টেশনটি আরও পাঠযোগ্য ফর্ম্যাটে রাখতে দেওয়ার জন্য স্যান্ডক্যাসলে চালিয়েছি । দস্তাবেজ সংরক্ষণাগারটি আনজিপ করুন এবং সূচিপত্র html দেখুন

অন্যান্য অনেক গুডির মধ্যে এটি প্রত্যাশিত ফরইচ বাস্তবায়ন সরবরাহ করে। এটি আপনাকে এই জাতীয় কোড লিখতে দেয়:

int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8 };

numbers.ForEach(x => Console.WriteLine(x*x));

2
ইন্টারেক্টিভ এক্সটেনশনের কাজের লিঙ্ক: মাইক্রোসফ্ট
ডাউনলোড /en/details.aspx?id=27203

8

পিনকিউ অনুসারে (নেট নেট ৪.০ থেকে পাওয়া যায়), আপনি এটি করতে পারেন

IEnumerable<T>.AsParallel().ForAll() 

একটি IEnumerable উপর সমান্তরাল foreach লুপ করতে।


যতক্ষণ না আপনার অ্যাকশন থ্রেডসেফ থাকে ততক্ষণ ভাল। তবে যদি আপনার সম্পাদনা করার জন্য একটি থ্রেড-ননফ কর্ম আছে? এটি বেশ
বিঘ্ন ঘটতে পারে

2
সত্য। এটি থ্রেড নিরাপদ নয়, কিছু থ্রেড পুল থেকে বিভিন্ন থ্রেড ব্যবহৃত হবে ... এবং আমার উত্তরটি সংশোধন করা দরকার। এখনই চেষ্টা করার সময় কোনও ফরইচ () নেই .. আমি যখন এটিকে চিন্তা করেছিলাম তখন অবশ্যই অবশ্যই অবশ্যই আমার কোডটি ফরইচ সহ এক্সটেনশনযুক্ত containing
ওল্ফ 5

6

পার্শ্ব প্রতিক্রিয়া ঘটানো ফোরইচের উদ্দেশ্য। আইমনামেবল একটি সেট অলস গণনার জন্য।

আপনি যখন বিবেচনা করবেন তখন এই ধারণাগত পার্থক্যটি বেশ দৃশ্যমান।

SomeEnumerable.ForEach(item=>DataStore.Synchronize(item));

আপনি "গণনা" বা "টোললিস্ট ()" বা এটির কিছু না করা পর্যন্ত এটি কার্যকর হবে না। এটা পরিষ্কারভাবে প্রকাশিত হয় না।

পুনরাবৃত্তির চেইন স্থাপনের জন্য তাদের স্বতন্ত্র উত্স এবং শর্তাদির মাধ্যমে সামগ্রী নির্ধারণের জন্য আপনার IEnumerable এক্সটেনশনগুলি ব্যবহার করা উচিত। এক্সপ্রেশন গাছগুলি শক্তিশালী এবং দক্ষ, তবে আপনার প্রকৃতির প্রশংসা করতে আপনার শিখতে হবে। এবং অলস মূল্যায়ন ওভাররাইড করে কয়েকটি অক্ষর সংরক্ষণ করার জন্য কেবল তাদের চারপাশের প্রোগ্রামিংয়ের জন্য নয়।


5

অনেকে এটি উল্লেখ করেছেন, তবে আমার এটি লিখতে হয়েছিল। এটি কি সবচেয়ে পরিষ্কার / সর্বাধিক পাঠযোগ্য?

IEnumerable<Item> items = GetItems();
foreach (var item in items) item.DoStuff();

সংক্ষিপ্ত এবং সাধারণ (স্ট্যান্ড)


আপনি পুরো প্রথম লাইনটি ফেলে দিতে পারেন এবং সরাসরি ব্যবহারের জন্য গেটইটেমগুলি ব্যবহার করতে পারেন
tymtam

3
অবশ্যই. এটি স্পষ্টতার জন্য এইভাবে লেখা হয়েছে। যাতে কোন GetItems()পদ্ধতিটি ফিরে আসে তা পরিষ্কার হয়ে যায় ।
নেনাড

4
এখন যখন আমি আমার মন্তব্য পড়ি তখন মনে হয় আমি এমন কিছু বলছি যা আপনি জানেন না। আমি এটা বোঝাতে চাইনি। আমি যা বোঝাতে চেয়েছি তা foreach (var item in GetItems()) item.DoStuff();হ'ল কেবল একটি সৌন্দর্য।
tymtam

4

এখন আমাদের কাছে বিকল্প রয়েছে ...

        ParallelOptions parallelOptions = new ParallelOptions();
        parallelOptions.MaxDegreeOfParallelism = 4;
#if DEBUG
        parallelOptions.MaxDegreeOfParallelism = 1;
#endif
        Parallel.ForEach(bookIdList, parallelOptions, bookID => UpdateStockCount(bookID));

অবশ্যই, এটি থ্রেডওয়ার্মগুলির সম্পূর্ণ নতুন ক্যান খুলবে।

PS (হরফের জন্য দুঃখিত, এটি সিস্টেম সিদ্ধান্ত নিয়েছে)


4

অসংখ্য উত্তর ইতিমধ্যে ইঙ্গিত হিসাবে, আপনি সহজেই নিজের মতো একটি এক্সটেনশন পদ্ধতি যুক্ত করতে পারেন। তবে, আপনি যদি এটি না করতে চান তবে আমি ছাত্রলীগের মধ্যে এই জাতীয় কিছু সম্পর্কে অবগত না থাকলেও নাম স্পেসে এখনও একটি বিকল্প রয়েছে System, যদি আপনার ইতিমধ্যে প্রতিক্রিয়াশীল এক্সটেনশনের কোনও রেফারেন্স থাকে (এবং যদি আপনি না করেন তবে , তোমার উচিত ছিল):

using System.Reactive.Linq;

items.ToObservable().Subscribe(i => i.DoStuff());

যদিও পদ্ধতির নামগুলি কিছুটা আলাদা তবে শেষ ফলাফলটি আপনি যা খুঁজছেন ঠিক তা-ই।


দেখে মনে হচ্ছে package প্যাকেজটি এখন
অবচয়

3

Foreach এও হতে পারে শৃঙ্খলিত , শুধু কর্ম পর pileline ফিরে দিলেন। সাবলীল থাকুন


Employees.ForEach(e=>e.Act_A)
         .ForEach(e=>e.Act_B)
         .ForEach(e=>e.Act_C);

Orders  //just for demo
    .ForEach(o=> o.EmailBuyer() )
    .ForEach(o=> o.ProcessBilling() )
    .ForEach(o=> o.ProcessShipping());


//conditional
Employees
    .ForEach(e=> {  if(e.Salary<1000) e.Raise(0.10);})
    .ForEach(e=> {  if(e.Age   >70  ) e.Retire();});

বাস্তবায়নের একটি আগ্রহী সংস্করণ।

public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enu, Action<T> action)
{
    foreach (T item in enu) action(item);
    return enu; // make action Chainable/Fluent
}

সম্পাদনা করুন: একটি অলস সংস্করণ এই জাতীয় উপার্জনের রিটার্ন ব্যবহার করছে ।

public static IEnumerable<T> ForEachLazy<T>(this IEnumerable<T> enu, Action<T> action)
{
    foreach (var item in enu)
    {
        action(item);
        yield return item;
    }
}

অলস সংস্করণ চাহিদা উদাহরণস্বরূপ রূপায়িত করতে হবে, ToList (), অন্যথায়, কিছুই ঘটবে। টুলমেকারস্টাইভের দুর্দান্ত মন্তব্যগুলি নীচে দেখুন।

IQueryable<Product> query = Products.Where(...);
query.ForEachLazy(t => t.Price = t.Price + 1.00)
    .ToList(); //without this line, below SubmitChanges() does nothing.
SubmitChanges();

আমি আমার লাইব্রেরিতে ফরইচ () এবং ফোরএচএলজি () উভয়ই রাখি।


2
আপনি কি এটি পরীক্ষা করেছেন? বেশ কয়েকটি প্রসঙ্গ রয়েছে যেখানে এই পদ্ধতিটি স্বজ্ঞাতভাবে বিপরীত আচরণ করে। আরও ভাল হবেforeach(T item in enu) {action(item); yield return item;}
Taemyr

2
এটি একাধিক গণনার ফলস্বরূপ হবে

মজাদার. ভাবছি যখন আমি উপরেরটি করতে চাই, 3 ক্রমের ক্রমের পরিবর্তে foreach (T item in enu) { action1(item); action2(item); action3(item); }? একটি একক, সুস্পষ্ট, লুপ। আমার ধারণা , অ্যাকশন 2 এর কাজ শুরু করার আগে সমস্ত অ্যাকশন 1 এর আগে কাজ করা গুরুত্বপূর্ণ ছিল কিনা ।
নির্মাতা স্টিভ

@ আরএম 558 - "ফলন ফেরত" ব্যবহার করে আপনার পদ্ধতি approach প্রো: কেবলমাত্র একবারের মূল ক্রমকে গণ্য করে, তাই বিস্তৃত গণনার সাথে সঠিকভাবে কাজ করে। কন: যদি আপনি ভুলে যান ".ToArray ()" শেষে, কিছুই হয় না। যদিও ব্যর্থতা সুস্পষ্ট হবে, দীর্ঘ সময়ের জন্য অবহেলিত নয়, তাই কোনও বড় ব্যয় হবে না। আমার কাছে "পরিষ্কার বোধ করেন না", তবে যদি কেউ এই রাস্তাটি (একজন ফোরইচ অপারেটর) নামছে তবে সঠিক বাণিজ্য right
স্টিভ

1
এই কোডটি লেনদেনের দৃষ্টিকোণ থেকে নিরাপদ নয়। যদি এটি ব্যর্থ হয় ProcessShipping()? আপনি ক্রেতাকে ইমেল করেন, তার ক্রেডিট কার্ডটি চার্জ করেন, তবে তাকে কখনও তাঁর জিনিস পাঠান না? অবশ্যই সমস্যা জিজ্ঞাসা।
zmechanic

2

এই "কার্যকরী পদ্ধতির" বিমূর্ততা বড় সময় ফাঁস করে। ভাষা স্তরের কিছুই পার্শ্ব প্রতিক্রিয়া রোধ করে না। যতক্ষণ আপনি এটিকে কনটেইনারটির প্রতিটি উপাদানগুলির জন্য আপনার ল্যাম্বদা / প্রতিনিধি হিসাবে কল করতে পারবেন - আপনি "ফোরইচ" আচরণ পাবেন।

উদাহরণস্বরূপ, ডেস্টডোরিয়ায় সিআরসিডি অভিধানটি মার্জ করার একটি উপায় (যদি ইতিমধ্যে কী উপস্থিত থাকে - ওভাররাইট)

এটি একটি হ্যাক, এবং কোনও উত্পাদন কোডে ব্যবহার করা উচিত নয়।

var b = srcDictionary.Select(
                             x=>
                                {
                                  destDictionary[x.Key] = x.Value;
                                  return true;
                                }
                             ).Count();

6
যদি আপনাকে সেই দাবি অস্বীকার করতে হয় তবে আপনার সম্ভবত এটি পোস্ট করা উচিত নয়। শুধুমাত্র আমার অভিমত.
অ্যান্ড্রু গ্রোথ

2
এর চেয়ে ভাল আর foreach(var tuple in srcDictionary) { destDictionary[tuple.Key] = tuple.Value; }কী করে? যদি প্রোডাকশন কোডে না থাকে তবে আপনি কখন এবং কেন এটি ব্যবহার করবেন?
মার্ক সোওুল

3
এটি কেবল এটি দেখানোর জন্য নীতিগতভাবে সম্ভব। ওপি যা যা চেয়েছিল তা করার জন্যও এটি ঘটে এবং আমি স্পষ্টভাবে ইঙ্গিত দিয়েছিলাম যে এটি উত্পাদনে ব্যবহার করা উচিত নয়, এখনও কৌতূহলী এবং শিক্ষামূলক মূল্য রয়েছে।
জার শারদান

2

জন স্কিট দ্বারা অনুপ্রাণিত হয়ে আমি নিম্নলিখিতগুলির সাথে তার সমাধানটি প্রসারিত করেছি:

সম্প্রসারণ পদ্ধতি:

public static void Execute<TSource, TKey>(this IEnumerable<TSource> source, Action<TKey> applyBehavior, Func<TSource, TKey> keySelector)
{
    foreach (var item in source)
    {
        var target = keySelector(item);
        applyBehavior(target);
    }
}

ক্লায়েন্ট:

var jobs = new List<Job>() 
    { 
        new Job { Id = "XAML Developer" }, 
        new Job { Id = "Assassin" }, 
        new Job { Id = "Narco Trafficker" }
    };

jobs.Execute(ApplyFilter, j => j.Id);

। । ।

    public void ApplyFilter(string filterId)
    {
        Debug.WriteLine(filterId);
    }

2

মোরলিংকের রয়েছে IEnumerable<T>.ForEachএবং আরও অনেকগুলি কার্যকর এক্সটেনশন। কেবল নির্ভরশীলতা নেওয়ার পক্ষে এটি উপযুক্ত নয়ForEach , তবে সেখানে প্রচুর দরকারী স্টাফ রয়েছে।

https://www.nuget.org/packages/morelinq/

https://github.com/morelinq/MoreLINQ


1

আমি লিঙ্ক এক্সটেনশন পদ্ধতিগুলি পার্শ্ব-প্রতিক্রিয়ামুক্ত হওয়া উচিত (এই কারণে নয় যে কোনও প্রতিনিধিই পার্শ্ব প্রতিক্রিয়া করতে পারে) এই ধারণার সাথে আমি সম্মানের সাথে একমত নই।

নিম্নোক্ত বিবেচনা কর:

   public class Element {}

   public Enum ProcessType
   {
      This = 0, That = 1, SomethingElse = 2
   }

   public class Class1
   {
      private Dictionary<ProcessType, Action<Element>> actions = 
         new Dictionary<ProcessType,Action<Element>>();

      public Class1()
      {
         actions.Add( ProcessType.This, DoThis );
         actions.Add( ProcessType.That, DoThat );
         actions.Add( ProcessType.SomethingElse, DoSomethingElse );
      }

      // Element actions:

      // This example defines 3 distict actions
      // that can be applied to individual elements,
      // But for the sake of the argument, make
      // no assumption about how many distict
      // actions there may, and that there could
      // possibly be many more.

      public void DoThis( Element element )
      {
         // Do something to element
      }

      public void DoThat( Element element )
      {
         // Do something to element
      }

      public void DoSomethingElse( Element element )
      {
         // Do something to element
      }

      public void Apply( ProcessType processType, IEnumerable<Element> elements )
      {
         Action<Element> action = null;
         if( ! actions.TryGetValue( processType, out action ) )
            throw new ArgumentException("processType");
         foreach( element in elements ) 
            action(element);
      }
   }

উদাহরণটি যা দেখায় তা হ'ল এক ধরণের দেরি-বাঁধাই যা ক্রিয়াকে সংজ্ঞায়িত করে মানটিকে ডিকোড করার জন্য একটি বড় স্যুইচ কন্সট্রাক্ট লিখতে না পেরে উপাদানগুলির ক্রমের উপর পার্শ্ব-প্রতিক্রিয়াযুক্ত অনেকগুলি সম্ভাব্য ক্রিয়াকলাপগুলির মধ্যে একটিকেই অনুরোধ করে one এটি এর সম্পর্কিত পদ্ধতিতে


9
কোনও এক্সটেনশন পদ্ধতির পার্শ্ব-প্রতিক্রিয়া থাকতে পারে এবং এটি হওয়া উচিত কিনা এর মধ্যে পার্থক্য রয়েছে। আপনি কেবল এটি দেখিয়ে দিচ্ছেন যে এটি থাকতে পারে, যখন তাদের পক্ষে কোনও পার্শ্ব প্রতিক্রিয়া হওয়া উচিত নয় এমন প্রস্তাব করার খুব ভাল কারণ থাকতে পারে। ফাংশনাল প্রোগ্রামিংয়ে, সমস্ত ফাংশনগুলি পার্শ্ব-প্রতিক্রিয়া মুক্ত, এবং ফাংশনাল প্রোগ্রামিং কনস্ট্রাক্টস ব্যবহার করার সময় আপনি ধরে নিতে পারেন যে সেগুলি।
ডেভ ভ্যান ডেন আইন্দে

1

সাবলীল থাকার জন্য কেউ এ জাতীয় কৌশল ব্যবহার করতে পারেন:

GetItems()
    .Select(i => new Action(i.DoStuf)))
    .Aggregate((a, b) => a + b)
    .Invoke();

0

VB.NET এর জন্য আপনার ব্যবহার করা উচিত:

listVariable.ForEach(Sub(i) i.Property = "Value")

দ্রষ্টব্য: এটি কেবলমাত্র প্রনয়ন যদি আপনি একটি Listঅথবা IList। একটি সাধারণের IEnumerableজন্য , গৃহীত উত্তরের ফরইচ এক্সটেনশন পদ্ধতির সমতুল্য ভিবি লিখুন ।
নির্মাতা স্টিভ

-1

তবুও অন্য একটি ForEachউদাহরণ

public static IList<AddressEntry> MapToDomain(IList<AddressModel> addresses)
{
    var workingAddresses = new List<AddressEntry>();

    addresses.Select(a => a).ToList().ForEach(a => workingAddresses.Add(AddressModelMapper.MapToDomain(a)));

    return workingAddresses;
}

4
কি স্মৃতি নষ্ট। এটি তালিকাকে একটি তালিকায় যুক্ত করার জন্য কল করে। কেন এটি কেবল ঠিকানাগুলি ফেরত দেয় না? নির্বাচন করুন (a => ম্যাপটোডোমাইন (ক))?
মার্ক সোওুল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.