জাভাস্ক্রিপ্টে ভবিষ্যদ্বাণী করার সময় অ্যারের মানগুলি পরিবর্তন করা সম্ভব?


300

উদাহরণ:

var arr = ["one","two","three"];

arr.forEach(function(part){
  part = "four";
  return "four";
})

alert(arr);

অ্যারেটি এখনও এটির মূল মানগুলির সাথে রয়েছে, পুনরাবৃত্তি ফাংশন থেকে অ্যারের উপাদানগুলিতে লেখার অ্যাক্সেসের কোনও উপায় আছে কি?


1
সংশ্লিষ্ট: stackoverflow.com/q/6081868/632951
Pacerier

মানচিত্রটি চেষ্টা করুন ( বিকাশকারী.মোজিলা.আর.ইন- x=[2,3,4]; x=x.map(n=>n*2); // [4,6,8]
জাস্টিন

উত্তর:


468

কলব্যাকটি উপাদান, সূচক এবং অ্যারে নিজেই পেরিয়ে যায়।

arr.forEach(function(part, index, theArray) {
  theArray[index] = "hello world";
});

সম্পাদনা করুন - একটি মন্তব্যে উল্লিখিত হিসাবে, .forEach()ফাংশনটি দ্বিতীয় যুক্তি নিতে পারে, যা thisপ্রতিটি কলটিতে কলব্যাকের মান হিসাবে ব্যবহৃত হবে :

arr.forEach(function(part, index) {
  this[index] = "hello world";
}, arr); // use arr as this

সেই দ্বিতীয় উদাহরণটি কলব্যাকের arrমতোই নিজেকে সেট আপ করা দেখায় thisneএকজন মনে করতে পারে যে .forEach()কলটিতে জড়িত অ্যারে এর ডিফল্ট মান হতে পারে this, তবে যে কারণেই হোক না কেন; thisহতে হবে undefinedযে দ্বিতীয় যুক্তি দেওয়া হয় না।

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

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

  • forEach অ্যারেতে প্রতিটি প্রবেশের সাথে বা কিছু করার জন্য;
  • filter শুধুমাত্র যোগ্যতা অর্জনকারী এন্ট্রি সমন্বিত একটি নতুন অ্যারে উত্পাদন করার জন্য;
  • map একটি বিদ্যমান অ্যারে রূপান্তর করে এক থেকে এক নতুন অ্যারে তৈরির জন্য;
  • some অ্যারেতে অন্তত একটি উপাদান কিছু বিবরণ ফিট করে কিনা তা পরীক্ষা করতে;
  • everyঅ্যারেতে থাকা সমস্ত এন্ট্রি বর্ণনার সাথে মেলে কিনা তা পরীক্ষা করতে ;
  • find একটি অ্যারেতে একটি মান সন্ধান করতে

ইত্যাদি। MDN লিঙ্ক


34
ধন্যবাদ! ES6: arr.forEach ((o, i, a) => a [i] = myNewVal)
দিয়েগোআরাকেরো

কেন part(বা এমনকি oএস 6 এও) অপরিবর্তিত? পুনরাবৃত্ত মান পেতে কিভাবে?
ড্যানিল মাশকিন

@DaniilMashkin partহবে undefinedযদি অ্যারের একটি উপাদান অ্যাসাইন করা হয়েছে undefinedস্পষ্টভাবে। একটি অ্যারের "খালি" স্লট (কোনও অ্যারে এন্ট্রি যা কখনই কোনও মান নির্ধারিত হয়নি) এড়িয়ে যায় .forEach()এবং বেশিরভাগ অন্যান্য অ্যারে পুনরুক্তি পদ্ধতিগুলি এড়িয়ে যায় ।
পয়েন্টি

2
সম্পূর্ণতার জন্য, .forEach()দ্বিতীয় যুক্তিও লাগে thisArg, যা আপনি thisকলব্যাকের অভ্যন্তরে ব্যবহার করতে পারেন । দ্রষ্টব্য: .forEachএটি কলব্যাকের একটি আর্গুমেন্ট নয় an
মহা সর্বশক্তিমান উট

3
ব্যবহার করার জন্য thisদ্বিতীয় আর্গুমেন্ট হিসাবে পাস .forEach(), আপনি সিনট্যাক্স ব্যবহার কলব্যাক ফাংশন পাস করতে হবে function()ES6 তীর ফাংশন ব্যবহার করে যেহেতু, () => {}বাঁধাই করা প্রসঙ্গ নেই।
jpena

131

আসুন এটি সহজ রাখার চেষ্টা করব এবং এটি আসলে কীভাবে কাজ করছে তা নিয়ে আলোচনা করুন। এটি পরিবর্তনশীল ধরণের এবং ফাংশন পরামিতিগুলির সাথে করতে হবে।

আপনার কোডটি আমরা এখানে বলছি:

var arr = ["one","two","three"];

arr.forEach(function(part) {
  part = "four";
  return "four";
})

alert(arr);

প্রথমে, এখানে আপনাকে অ্যারে.প্রোটোটাইপ.অফার ()) সম্পর্কে পড়তে হবে:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

দ্বিতীয়ত, আসুন জাভাস্ক্রিপ্টে মান ধরণের সম্পর্কে সংক্ষেপে কথা বলি।

প্রিমিটিভ (অপরিজ্ঞাত, নাল, স্ট্রিং, বুলিয়ান, সংখ্যা) একটি আসল মান সঞ্চয় করে।

উদা: var x = 5;

রেফারেন্সের প্রকারগুলি (কাস্টম অবজেক্টস) বস্তুর মেমরির অবস্থান সংরক্ষণ করে।

উদা: var xObj = { x : 5 };

এবং তৃতীয়ত, কীভাবে ফাংশন প্যারামিটারগুলি কাজ করে।

ফাংশনগুলিতে, পরামিতি সর্বদা মান দ্বারা পাস হয়।

কারণ arrস্ট্রিংগুলির একটি অ্যারে, এটি আদিম বস্তুর একটি অ্যারে , যার অর্থ তারা মান দ্বারা সঞ্চিত হয়।

সুতরাং উপরের আপনার কোডের জন্য, এর অর্থ হ'ল প্রতিবারের জন্য () পুনরাবৃত্তি partহয় arr[index], তবে একই বস্তুর চেয়ে একই মানের সমান হয় ।

part = "four";পরিবর্তনশীল পরিবর্তন করবে part, তবে arrএকা চলে যাবে ।

নিম্নলিখিত কোডটি আপনার ইচ্ছার মান পরিবর্তন করবে:

var arr = ["one","two","three"];

arr.forEach(function(part, index) {
  arr[index] = "four";
});

alert(arr);

এখন যদি অ্যারেটি রেফারেন্স ধরণেরarr একটি অ্যারে ছিল তবে নিম্নলিখিত কোডটি কাজ করবে কারণ রেফারেন্স টাইপগুলি প্রকৃত বস্তুর পরিবর্তে কোনও বস্তুর একটি মেমরি অবস্থান সঞ্চয় করে।

var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];

arr.forEach(function(part, index) {
  // part and arr[index] point to the same object
  // so changing the object that part points to changes the object that arr[index] points to

  part.num = "four";
});

alert(arr[0].num);
alert(arr[1].num);
alert(arr[2].num);

নিম্নলিখিতটি চিত্রিত করে যে একাই partসঞ্চিত বস্তুগুলি রেখে আপনি একটি নতুন অবজেক্টের দিকে ইঙ্গিত করতে পরিবর্তন করতে পারেন arr:

var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];

arr.forEach(function(part, index) {
  // the following will not change the object that arr[index] points to because part now points at a new object
  part = 5;
});

alert(arr[0].num);
alert(arr[1].num);
alert(arr[2].num);

2
সত্যিই, দুর্দান্ত ব্যাখ্যা! অন্য পুনরাবৃত্ত পদ্ধতিতে ব্যাখ্যাটি আরও বাড়িয়ে দেওয়া আরও ভাল হত, ... এর জন্য, মানচিত্র, ... এর জন্য ... নতুন ক্ষেত্রে ... এর জন্য প্রতিটি ক্ষেত্রে যেমন ছিল না তার চেয়ে খুব অনুরূপভাবে কাজ করা " সূচক "শেষ পর্যন্ত মূল অ্যারে পরিবর্তনের জন্য অনুপস্থিত (যেমন প্রতিটি ক্ষেত্রে)। এছাড়াও ES5 মানচিত্র forEach এর অনুরূপ বলে মনে হতে পারে, কেবলমাত্র একটি মানচিত্র থেকে মানগুলি ফেরতের সম্ভাবনা সূচকটি ব্যবহার না করে সিনট্যাক্স দৃষ্টিকোণ থেকে বিষয়গুলি পরিষ্কার করে দেয়।
ক্রিস্টোফ ভিদাল

1
দুর্দান্ত ব্যাখ্যা। ধন্যবাদ. সর্বোপরি আমি এই বিবৃতিটি পেতে পারি না: In functions, parameters are always passed by value. দ্বিতীয় উদাহরণটির কী হবে?
অ্যালেক্স

@ S সাইডস, এই বিবৃতিটি বর্ণনা করছে যে ফাংশন পরামিতি সর্বদা মান দ্বারা পাস হবে। আদিমদের জন্য তাই এটি আদিম পয়েন্টটি মান করবে। অবজেক্টের জন্য, এটি সেই অবস্থান হবে যেখানে বস্তুটি নির্দেশ করছে। এই ডাব্লু 3 স্কুল পৃষ্ঠা একটি ভাল ব্যাখ্যা আছে। বিভাগগুলি দেখুন আর্গুমেন্টগুলি মান দ্বারা পাস হয় এবং অবজেক্টগুলি রেফারেন্স দ্বারা পাস হয়
ডেভ

ফাংশনগুলিতে, পরামিতি সর্বদা মান দ্বারা পাস হয়। BAM। ধন্যবাদ. +1
রডারবব

92

অ্যারে: [1, 2, 3, 4]
ফলাফল:["foo1", "foo2", "foo3", "foo4"]

Array.prototype.map() আসল অ্যারে রাখুন

const originalArr = ["Iron", "Super", "Ant", "Aqua"];
const modifiedArr = originalArr.map(name => `${name}man`);

console.log( "Original: %s", originalArr );
console.log( "Modified: %s", modifiedArr );

Array.prototype.forEach() মূল অ্যারে ওভাররাইড করুন

const originalArr = ["Iron", "Super", "Ant", "Aqua"];
originalArr.forEach((name, index) => originalArr[index] = `${name}man`);

console.log( "Overridden: %s", originalArr );


3
"অ্যারে.প্রোটোটাইপ.ম্যাপ () আর্ট ভেরিয়েবলটি পুনরায় নিয়োগের মাধ্যমে প্রাপ্ত মূল অ্যারেটি পরিবর্তন করুন"। ম্যাপ () কখনই আসল অ্যারে পরিবর্তন করে না, এটি একটি নতুন তৈরি করে। ভেরিয়েবলের পুনরায় নিয়োগটি মূল বস্তুকে পরিবর্তন করে না।
ভাদকৌ

1
let arr1 = ["1", 2, 3, 4]; arr1.map(function(v) { return "foo"+ v; }); console.log( arr ); অ্যারে.প্রোটোটাইপ.ম্যাপ () আসল অ্যারে কখনই সংশোধন করবেন না, প্রতিটি মিউটেটের জন্য।
অনুপম মৌর্য

@ অনুপমমৌর্য এটি মোটেও সত্য নয়। mapস্পষ্টতই এর অ্যারেটি পরিবর্তন করতে পারে forEachএবং সাধারণভাবে না।
ব্যবহারকারী4642212

@ সেবাস্তিয়ানসিমন, উত্তরের জন্য ধন্যবাদ। আমি সমস্ত যুক্ত করতে চাই, কারণ প্রত্যেকটি ডেটা ওভাররাইড করে, কিন্তু একটি মানচিত্র, এটি করতে পারে না, এটি একটি নতুন অনুলিপি তৈরি করে।
অনুপম মৌর্য

14

জাভাস্ক্রিপ্ট হ'ল মান দ্বারা পাস, এবং যার মূল অর্থ অ্যারেতে থাকা মানটির partএকটি অনুলিপি

মান পরিবর্তন করতে, নিজের লুপে অ্যারে নিজেই অ্যাক্সেস করুন।

arr[index] = 'new value';


এটি partঅনুলিপি করা হয়েছে কিনা তার উপর নির্ভর করে - যদিও আপনি ঠিক বলেছেন যে চলকটি কোনও পয়েন্টার নয়, তবে একটি মান
বার্গি

8
"জাভাস্ক্রিপ্ট হ'ল মূল্য দ্বারা পাস" বলা একটি স্থূল সাধারণীকরণ। জাভাস্ক্রিপ্টে রেফারেন্সের ধরণ রয়েছে। মান প্রকার মান দ্বারা পাস হয়।
অ্যালেক্স টারপিন

9
স্থূল সাধারণীকরণ নয়। একটি সম্পূর্ণ সঠিক এবং নিখুঁত বিবৃতি। জাভাস্ক্রিপ্ট মান দ্বারা রেফারেন্স পাস। জাভাস্ক্রিপ্ট সর্বদা মান দ্বারা পাস হয়।
hvgotcodes

1
@ বার্গি: না, এটি ধরণের বিষয় বিবেচনা করে না। সমস্ত মান অ্যাসাইনমেন্টে অনুলিপি করা হয় - জাভাস্ক্রিপ্টের একমাত্র মানগুলি আদিম এবং রেফারেন্স। প্রাথমিক ও রেফারেন্স উভয়ই অ্যাসাইনমেন্টে অনুলিপি করা হয়।
newacct

6
@ বার্গি কেবলমাত্র একটি ভাষার একটি উল্লেখ হিসাবে একটি জিনিস আছে বলে বোঝায় না, এটি রেফারেন্স দ্বারা পাস ব্যবহার করে না। রেফারেন্সগুলি মান দ্বারা পাস (এবং হয়) হতে পারে, অর্থাত রেফারেন্সের মানটি অনুলিপি করা হয় এবং সেই অনুলিপিটি আর্গুমেন্ট হিসাবে ব্যবহৃত হয়।
hvgotcodes

4

অ্যারের সূচক দিয়ে এটি প্রতিস্থাপন করুন।

array[index] = new_value;

2
শীতল ... সর্বদা কিছু ব্যাখ্যা যুক্ত করুন
devpro

4

একটি =>শৈলী ফাংশন ব্যবহার করে এখানে একটি অনুরূপ উত্তর :

var data = [1,2,3,4];
data.forEach( (item, i, self) => self[i] = item + 10 );

ফলাফল দেয়:

[11,12,13,14]

selfপরামিতি তীর শৈলী ফাংশন কঠোরভাবে প্রয়োজন নেই, তাই

data.forEach( (item,i) => data[i] = item + 10);

কাজ করে।


3

.ForEach ফাংশনটিতে একটি কলব্যাক ফাংশন থাকতে পারে (ইচেলেমেন্ট, এলিমেন্টইন্ডেক্স) সুতরাং মূলত আপনার যা করা উচিত তা হ'ল:

arr.forEach(function(element,index){
    arr[index] = "four";   //set the value  
});
console.log(arr); //the array has been overwritten.

অথবা আপনি যদি মূল অ্যারে রাখতে চান তবে উপরের প্রক্রিয়াটি করার আগে আপনি এর একটি অনুলিপি তৈরি করতে পারেন। অনুলিপি তৈরি করতে, আপনি ব্যবহার করতে পারেন:

var copy = arr.slice();

3
আপনি যদি অ্যারের একটি অনুলিপি তৈরি করতে চান তবে map()পরিবর্তে ব্যবহার করুন forEach()map()উত্স অ্যারের উপরে পুনরাবৃত্তি হয় এবং মূলটির [পরিবর্তিত] অনুলিপি সহ একটি নতুন অ্যারে প্রদান করে: উত্স অ্যারেটি অপরিবর্তিত রয়েছে।
নিকোলাস কেরি

2

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

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

এই কোডটি বিবেচনা করুন যেখানে আমরা সূচী পজিশনে আইটেমটি সূচী পজিশনে 5 এ সূচী পজিশনে 2 এ স্থানান্তর করি যখন একবার সূচী 5 অবধি গণনা করা হয়।

var ar = [0,1,2,3,4,5,6,7,8,9];
ar.forEach((e,i,a) => {
i == 5 && a.splice(2,0,a.splice(i,1)[0])
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 5 5 - 6 6 - 7 7 - 8 8 - 9 9

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

এই কোডটি বিবেচনা করুন যেখানে আমরা সূচকটি 5 অবধি গণনা করার পরে সূচি পজিশনে আইটেমটি সূচী অবস্থানে 7 এ স্থানান্তর করি।

var a = [0,1,2,3,4,5,6,7,8,9];
a.forEach((e,i,a) => {
i == 5 && a.splice(7,0,a.splice(i,1)[0])
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 5 5 - 6 7 - 7 5 - 8 8 - 9 9

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

var a = [0,1,2,3,4,5,6,7,8,9];
a.forEach((e,i,a) => {
i == 5 && (a.splice(7,0,a.splice(i,1)[0]), i--);
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 4 5 - 6 7 - 7 5 - 8 8 - 9 9

আপনি যখন দেখবেন যখন আমরা হ্রাস পেয়েছি তখন iএটি 5 থেকে 6 অবধি চলবে না, যেখানে থেকে এটি রেখেছিল।

তাই এটি মাথায় রাখুন।


1

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

let values = ["A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8"];
let count = 0;
values.slice().forEach((value, index) => {
    if (value === "A2" || value === "A5") {
        values.splice(index - count++, 1);
    };
});
console.log(values);

// Expected: [ 'A0', 'A1', 'A3', 'A4', 'A6', 'A7', 'A8' ]

আগে উপাদানগুলি সন্নিবেশ করতে:

if (value === "A0" || value === "A6" || value === "A8") {
    values.splice(index - count--, 0, 'newVal');
};

// Expected: ['newVal', A0, 'A1', 'A2', 'A3', 'A4', 'A5', 'newVal', 'A6', 'A7', 'newVal', 'A8' ]

এর পরে উপাদানগুলি সন্নিবেশ করতে:

if (value === "A0" || value === "A6" || value === "A8") {
    values.splice(index - --count, 0, 'newVal');
};

// Expected: ['A0', 'newVal', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'newVal', 'A7', 'A8', 'newVal']

কোনও উপাদান প্রতিস্থাপন করতে:

if (value === "A3" || value === "A4" || value === "A7") {
    values.splice(index, 1, 'newVal');
};

// Expected: [ 'A0', 'A1', 'A2', 'newVal', 'newVal', 'A5', 'A6', 'newVal', 'A8' ]

দ্রষ্টব্য: যদি 'আগে' এবং 'পরে' সন্নিবেশকারী উভয়ই প্রয়োগ করে, কোডটি আগে "আগে" সন্নিবেশ করানো উচিত, অন্য উপায়ে আশানুরূপ হবে না


0

আপনি যদি ওভাররাইড করতে চান তবে এটি চেষ্টা করতে পারেন

var newArray= [444,555,666];
var oldArray =[11,22,33];
oldArray.forEach((name, index) => oldArray [index] = newArray[index]);
console.log(newArray);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.