ভবিষ্যদ্বাণী এবং মানচিত্রের মধ্যে কি পার্থক্য আছে?


218

ঠিক আছে এটি একটি কম্পিউটার বিজ্ঞানের প্রশ্ন, নির্দিষ্ট ভাষার উপর ভিত্তি করে প্রশ্নের চেয়ে বেশি, তবে মানচিত্রের অপারেশন এবং ফোরচ অপারেশনের মধ্যে কি পার্থক্য রয়েছে? বা তারা কি একই জিনিসটির জন্য কেবল আলাদা নাম?


কৌতূহলজনকভাবে, যদি আমি এর Iterator[String]থেকে একটি পেয়ে scala.io.Source.fromFile("/home/me/file").getLines()এবং .foreach(s => ptintln(s))এটিতে প্রয়োগ করি তবে এটি ঠিক আছে তবে মুদ্রিত হয় তবে ঠিক পরে খালি হয়ে যায়। একই সাথে আমি যদি .map(ptintln(_))এটি প্রয়োগ করি - এটি খালি হয়ে যায় এবং কিছুই মুদ্রিত হয় না।
ইভান

উত্তর:


294

আলাদা।

পূর্বাভাস একটি তালিকার উপরে পুনরাবৃত্তি করে এবং প্রতিটি তালিকা সদস্যের পার্শ্ব প্রতিক্রিয়া সহ কিছু ক্রিয়াকলাপ প্রয়োগ করে (যেমন উদাহরণস্বরূপ ডাটাবেজে প্রতিটি একটিকে সংরক্ষণ করা)

মানচিত্রটি তালিকার উপরে পুনরাবৃত্তি করে, সেই তালিকার প্রতিটি সদস্যকে রূপান্তর করে এবং রূপান্তরিত সদস্যদের সাথে একই আকারের অন্য একটি তালিকা ফেরত দেয় (যেমন স্ট্রিংগুলির একটি তালিকা বড় হাতের দিকে রূপান্তর করে)


ধন্যবাদ, আমি ভেবেছিলাম এটি এই লাইন বরাবর কিছু ছিল তবে নিশ্চিত ছিল না!
রবার্ট গোল্ড

19
: কিন্তু আপনি পার্শ্ব প্রতিক্রিয়া এই উত্তরটি মত মানচিত্র ফাংশন too.I ঘটতে পারে stackoverflow.com/a/4927981/375688
TinyTimZamboni

6
উল্লেখ এক গুরুত্বপূর্ণ পয়েন্ট (এই Scala মধ্যে বিশেষ করে সত্য) যে একটি কল mapকরে না যখন প্রত্যাশিত রুপান্তরিত তালিকা তলব করা হয় যতক্ষণ না তার অন্তর্নিহিত লজিক সঞ্চালনের স্থাপিত। বিপরীতে, foreachএর অপারেশন অবিলম্বে গণনা করা হয়।
বিগটিটি

124

তাদের মধ্যে গুরুত্বপূর্ণ পার্থক্যটি হ'ল mapসমস্ত ফলাফল সংগ্রহের মধ্যে জমা করে, যেখানে foreachকিছুই দেয় না। mapসাধারণত যখন আপনি কোনও ফাংশন সহ উপাদানগুলির একটি সংগ্রহকে রূপান্তর করতে চান তখন ব্যবহৃত হয়, যখন foreachপ্রতিটি উপাদানটির জন্য কেবল কোনও ক্রিয়া সম্পাদন করে।


ধন্যবাদ! এখন আমি পার্থক্য বুঝতে পারি। এটি বেশ কিছু সময়ের জন্য আমার কাছে বিরক্তিকর ছিল
রবার্ট গোল্ড

এছাড়াও খুব গুরুত্বপূর্ণ!
14 Тернер

40

সংক্ষেপে, foreachউপাদান সংগ্রহের প্রতিটি উপাদানটিতে একটি অপারেশন প্রয়োগ করার জন্য, অন্যদিকে mapএকটি সংগ্রহকে অন্য সংকলনে রূপান্তর করার জন্য।

তার মাঝে দুটি উল্লেখযোগ্য পার্থক্য আছে foreachএবং map

  1. foreachএটি প্রয়োগ করা অপারেশনটিতে কোনও ধারণামূলক বিধিনিষেধ নেই, সম্ভবত কোনও উপাদানকে যুক্তি হিসাবে গ্রহণ করুন। অর্থাৎ, অপারেশনটি কিছুই করতে পারে না, এর পার্শ্ব-প্রতিক্রিয়া থাকতে পারে, মান দিতে পারে বা মান ফেরত দিতে পারে না। সমস্ত foreachযত্নশীল উপাদানগুলির সংগ্রহের মাধ্যমে পুনরাবৃত্তি হওয়া এবং প্রতিটি উপাদানটিতে অপারেশন প্রয়োগ করা apply

    mapঅন্যদিকে, অপারেশনটিতে কোনও বিধিনিষেধ রয়েছে: এটি অপারেশনটিকে কোনও উপাদান ফেরত দেবে বলে প্রত্যাশা করে এবং সম্ভবত কোনও উপাদানকে তর্ক হিসাবেও মেনে নেয়। mapঅপারেশন উপাদানের একটি সংগ্রহ উপর iterates, প্রতিটি উপাদান অপারেশন প্রয়োগ, এবং পরিশেষে অন্য সংগ্রহে মধ্যে অপারেশন প্রতিটি আবাহন ফল সংরক্ষণ। অন্য কথায়, একটি সংগ্রহকে অন্যটিতে map রূপান্তরিত করে।

  2. foreachউপাদানগুলির একক সংগ্রহের সাথে কাজ করে। এটি ইনপুট সংগ্রহ।

    map দুটি উপাদানের সংগ্রহের সাথে কাজ করে: ইনপুট সংগ্রহ এবং আউটপুট সংগ্রহ।

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

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

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


কিভাবে একটি উদাহরণ .forEach()প্রয়োগ করতে ব্যবহৃত হতে পারে .map(): এখানে দেখতে stackoverflow.com/a/39159854/1524693
Chinoto Vokro

32

Array.protototype.mapপদ্ধতি এবং Array.protototype.forEachউভয়ই বেশ একই রকম।

নিম্নলিখিত কোডটি চালান: http://labs.codecademy.com/bw1/6# : ওয়ার্কস্পেস

var arr = [1, 2, 3, 4, 5];

arr.map(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
});

console.log();

arr.forEach(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
});

তারা সঠিক ditto ফলাফল দেয়।

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

আপনি যখন নিম্নলিখিত কোডটি চালান তখন টুইস্টটি আসে: -

এখানে আমি মানচিত্র এবং প্রতিটি পদ্ধতি থেকে রিটার্ন মানটির ফলাফলটি সহজভাবে অর্পণ করেছি।

var arr = [1, 2, 3, 4, 5];

var ar1 = arr.map(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
    return val;
});

console.log();
console.log(ar1);
console.log();

var ar2 = arr.forEach(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
    return val;
});

console.log();
console.log(ar2);
console.log();

এখন ফলাফল কিছু জটিল!

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

[ 1, 2, 3, 4, 5 ]

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

undefined

উপসংহার

Array.prototype.mapএকটি অ্যারের ফিরিয়ে Array.prototype.forEachদেয় কিন্তু দেয় না। সুতরাং আপনি মানচিত্রের পদ্ধতিতে প্রেরিত কলব্যাক ফাংশনের অভ্যন্তরে ফিরে আসা অ্যারে হেরফের করতে পারেন এবং তারপরে এটি ফিরিয়ে আনতে পারেন।

Array.prototype.forEach কেবলমাত্র প্রদত্ত অ্যারে দিয়ে হাঁটেন যাতে অ্যারে চলার সময় আপনি আপনার জিনিসগুলি করতে পারেন।


11

সর্বাধিক 'দৃশ্যমান' পার্থক্য হ'ল মানচিত্রটি একটি নতুন সংগ্রহের ফলাফল সংগ্রহ করে, যখন পূর্বাভাসটি কেবলমাত্র সম্পাদনের জন্য করা হয়।

তবে কয়েকটি অতিরিক্ত অনুমান রয়েছে: যেহেতু মানচিত্রের 'উদ্দেশ্য' হ'ল মূল্যগুলির নতুন তালিকা, তাই এটি বাস্তবায়নের ক্রমকে গুরুত্ব দেয় না। প্রকৃতপক্ষে, কিছু কার্যকর পরিবেশ সমান্তরাল কোড উত্পন্ন করে বা পুনরাবৃত্তি মান, বা অলসতার জন্য কল এড়াতে কিছু এড়াতে কিছু স্মৃতিচারণের প্রবর্তন করে, যাতে কিছু কল করা এড়াতে পারে না।

অন্যদিকে, foreach বিশেষত পার্শ্ব প্রতিক্রিয়া জন্য ডাকা হয়; সুতরাং আদেশটি গুরুত্বপূর্ণ, এবং সাধারণত সমান্তরাল হতে পারে না।


11

সংক্ষিপ্ত উত্তর: map এবং forEachপৃথক। এছাড়াও, অনানুষ্ঠানিকভাবে বলা, mapএটির একটি কঠোর সুপারসেট forEach

দীর্ঘ উত্তর: প্রথমে আসুন এর এক লাইন বিবরণ forEachএবং map:

  • forEach প্রত্যেকটিতে সরবরাহকৃত ক্রিয়াকলাপকে কল করে সমস্ত উপাদানকে পুনরুক্ত করে।
  • map প্রত্যেকটিতে সরবরাহিত ফাংশনটি কল করে সমস্ত উপাদানগুলির উপরে পুনরাবৃত্তি ঘটে এবং প্রতিটি ফাংশন কলের ফলাফল মনে করে একটি রূপান্তরিত অ্যারে তৈরি করে।

অনেক ভাষায়, forEachপ্রায়ই বলা হয় ন্যায়বিচার each। নিম্নলিখিত আলোচনাটি কেবল রেফারেন্সের জন্য জাভাস্ক্রিপ্ট ব্যবহার করে। এটি সত্যিই অন্য কোনও ভাষা হতে পারে।

এখন, এই ফাংশনগুলির প্রতিটি ব্যবহার করি।

ব্যবহার forEach:

টাস্ক 1: একটি ফাংশন লিখুন printSquares, যা সংখ্যার অ্যারে গ্রহণ করে arrএবং এতে প্রতিটি উপাদানের বর্গক্ষেত্র মুদ্রণ করে।

সমাধান 1:

var printSquares = function (arr) {
    arr.forEach(function (n) {
        console.log(n * n);
    });
};

ব্যবহার map:

টাস্ক 2: একটি ফাংশন লিখুন selfDot, যা সংখ্যার অ্যারে গ্রহণ করে arr, এবং একটি অ্যারে প্রদান করে যার মধ্যে প্রতিটি উপাদানটি সংশ্লিষ্ট উপাদানের বর্গ হয় arr

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

সমাধান 2:

var selfDot = function (arr) {
    return arr.map(function (n) {
        return n * n;
    });
};

mapসুপারস্টার কেমন আছেন forEach?

টাস্ক 1 এবং টাস্ক 2map উভয় টাস্কের সমাধান করতে আপনি ব্যবহার করতে পারেন । তবে, আপনি টাস্ক 2 সমাধান করার জন্য ব্যবহার করতে পারবেন না ।forEach

ইন সমাধান 1 , যদি আপনি কেবল প্রতিস্থাপন forEachদ্বারা map, সমাধান এখনও বৈধ হতে হবে। ইন সমাধান 2 অবশ্য প্রতিস্থাপন mapদ্বারা forEachআপনার পূর্বে কাজ সমাধান ভঙ্গ করবে।

বাস্তবায়নকারী forEachপরিপ্রেক্ষিতে map:

mapএর শ্রেষ্ঠত্ব উপলব্ধি করার আরেকটি উপায় হল forEachশর্তাবলী কার্যকর করা map। যেহেতু আমরা ভাল প্রোগ্রামার হচ্ছি আমরা নেমস্পেস দূষণে জড়িত হব না। আমরা আমাদের কল করব forEach, ঠিক each

Array.prototype.each = function (func) {
    this.map(func);
};

এখন, আপনি যদি prototypeবাজে কথা পছন্দ না করেন তবে এখানে যান:

var each = function (arr, func) {
    arr.map(func); // Or map(arr, func);
};

সুতরাং, উম্ম .. forEachএমনকি কেন বিদ্যমান?

উত্তরটি হ'ল দক্ষতা। আপনি যদি অ্যারেটিকে অন্য অ্যারে রূপান্তর করতে আগ্রহী না হন তবে আপনার কেন রূপান্তর অ্যারে গণনা করা উচিত? শুধু এটাকে ফেলে দেই? অবশ্যই না! আপনি যদি রূপান্তর চান না, আপনার কোনও রূপান্তর করা উচিত নয়।

সুতরাং টাস্ক 1 সমাধান করার জন্য মানচিত্রটি ব্যবহার করা যেতে পারে , সম্ভবত এটি করা উচিত নয়। প্রত্যেকের জন্য তার পক্ষে সঠিক প্রার্থী।


আসল উত্তর:

যদিও আমি মূলত @madlep এর উত্তর সাথে একমত, আমি যে বাতলান চাই map()একটি কঠোর সুপার সেট এর forEach()

হ্যাঁ, map()সাধারণত একটি নতুন অ্যারে তৈরি করতে ব্যবহৃত হয়। যাইহোক, এটা হতে পারে এছাড়াও বর্তমান অ্যারের পরিবর্তন করতে ব্যবহৃত হবে।

এখানে একটি উদাহরণ:

var a = [0, 1, 2, 3, 4], b = null;
b = a.map(function (x) { a[x] = 'What!!'; return x*x; });
console.log(b); // logs [0, 1, 4, 9, 16] 
console.log(a); // logs ["What!!", "What!!", "What!!", "What!!", "What!!"]

উপরের উদাহরণে, aসুবিধামত a[i] === iজন্য যে সেট ছিল i < a.length। তবুও, এটি এর শক্তি প্রদর্শন করে map()

এর সরকারী বিবরণ এখানেmap() । নোট যে map()এমনকি অ্যারে এটি বলা হয় পরিবর্তন করতে পারে! শিল map()!

আশা করি এটি সাহায্য করেছে।


10-নভেম্বর-2015 সম্পাদিত: বিস্তৃত বিবরণ।


-১, এটি কেবল জাভাস্ক্রিপ্টের আওতায় বৈধ; প্রশ্নটি বিশেষত ভাষা অজ্ঞেয় এবং কম্পিউটার বিজ্ঞান ধারণাগুলি সম্পর্কে কথা বলে, সীমিত বাস্তবায়ন নয়।
জাভিয়ের

1
@ জাভিয়ার: হুম .., আমি আমার উত্তর জাভাস্ক্রিপ্ট সুনির্দিষ্ট হওয়ার বিষয়ে আপনার সাথে একমত হতে পারি। তবে নিজেকে এটি জিজ্ঞাসা করুন: যদি কোনও ভাষার একটি স্থানীয় mapফাংশন থাকে তবে না forEach; আপনি কেবল mapপরিবর্তে ব্যবহার করতে পারবেন না forEach? ফ্লিপ দিকে, যদি কোনও ভাষা থাকে forEachতবে না map, আপনাকে নিজের প্রয়োগ করতে হবে map। আপনি কেবল forEachপরিবর্তে ব্যবহার করতে পারবেন না map। আমাকে বল তুমি কি ভাবছ.
সুমুখ বারভে

3

তালিকাগুলি ব্যবহার করে স্কালায় এখানে একটি উদাহরণ রয়েছে: মানচিত্রের তালিকা ফিরে আসে, পূর্বাঞ্চ কিছুই দেয় না।

def map(f: Int ⇒ Int): List[Int]
def foreach(f: Int ⇒ Unit): Unit

সুতরাং মানচিত্রটি প্রতিটি তালিকার উপাদানগুলিতে ফ ফাংশন প্রয়োগের ফলে তালিকাটি ফিরিয়ে দেয়:

scala> val list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)

scala> list map (x => x * 2)
res0: List[Int] = List(2, 4, 6)

ফরচ প্রতিটি এলিমেন্টে কেবল প্রযোজ্য:

scala> var sum = 0
sum: Int = 0

scala> list foreach (sum += _)

scala> sum
res2: Int = 6 // res1 is empty

2

আপনি যদি জাভাস্ক্রিপ্টের বিষয়ে বিশেষভাবে কথা বলছেন তবে পার্থক্যটি হ'ল এটি mapএকটি লুপ ফাংশন যখন একটি পুনরাবৃত্তিকারী forEach

mapআপনি যখন তালিকার প্রতিটি সদস্যের সাথে একটি অপারেশন প্রয়োগ করতে চান এবং মূল তালিকাটিকে প্রভাবিত না করে ফলাফলকে নতুন তালিকা হিসাবে ফিরে পেতে চান ব্যবহার করুন ।

ব্যবহার করুন forEachযখন আপনি করতে চান না তালিকাটির প্রতিটি উপাদানের ভিত্তিতে কিছু। উদাহরণস্বরূপ আপনি পৃষ্ঠাতে জিনিসগুলি যুক্ত করছেন। মূলত, যখন আপনি "পার্শ্ব প্রতিক্রিয়া" চান এটির জন্য দুর্দান্ত।

অন্যান্য পার্থক্য: forEachকিছুই প্রত্যাবর্তন করে না (যেহেতু এটি সত্যিকার অর্থে একটি নিয়ন্ত্রণ প্রবাহ ফাংশন), এবং পাস-ইন ফাংশন সূচক এবং পুরো তালিকার রেফারেন্স পায়, যেখানে মানচিত্র নতুন তালিকাটি দেয় এবং কেবলমাত্র বর্তমান উপাদানটিতে পাস করে।


0

ফরইচ কোনও ফাংশন প্রয়োগ করার চেষ্টা করে যেমন আরডিডির প্রতিটি উপাদানটিতে ডিবি ইত্যাদিতে লেখার মতো কিছু ফিরিয়ে না দিয়ে without

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

"মডেল> এ" <stdin> ", লাইন 5 ফাইল করুন

অ্যাট্রিবিউটআরার: 'ননটাইপ' অবজেক্টটির কোনও 'কালেক্ট' নেই

nums = sc.parallelize([1,2,3,4,5,6,7,8,9,10])
num2 = nums.map(lambda x: x+2)
print ("num2",num2.collect())
num3 = nums.foreach(lambda x : x*x)
print ("num3",num3.collect())
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.