একটি অ্যারের উপাদানটি একটি অ্যারের অবস্থান থেকে অন্য অ্যারে স্থানান্তর করুন


520

অ্যারে এলিমেন্টটি কীভাবে সরানো যায় তা নির্ধারণ করতে আমার বেশ কষ্ট হচ্ছে। উদাহরণস্বরূপ, নিম্নলিখিত দেওয়া:

var arr = [ 'a', 'b', 'c', 'd', 'e'];

আমি কীভাবে 'd'আগে যেতে একটি ফাংশন লিখতে পারি 'b'?

নাকি 'a'পরে 'c'?

সরানোর পরে, বাকি উপাদানগুলির সূচকগুলি আপডেট করা উচিত। এর অর্থ হ'ল সরানোর পরে প্রথম উদাহরণে [0] হবে = 'ক', আরার [1] = 'ডি' আরার [2] = 'বি', আরার [3] = 'সি', আরার [4] = 'ই'

এটি দেখতে বেশ সহজ হওয়া উচিত বলে মনে হচ্ছে, তবে আমি এটির চারপাশে আমার মাথা গুটিয়ে রাখতে পারি না।


3
ভাল এই প্রশ্নটি পুরানো তবে সোনার
জালাল

ES6const changeValuePosition = (arr, init, target) => {[arr[init],arr[target]] = [arr[target],arr[init]]; return arr}
মুহসাল্লা

এটি কেবলমাত্রে initএবং এ উপাদানগুলিকে অদলবদল করে target
ম্যাট এফ।

উত্তর:


671

আপনি যদি এনপিএম -এ কোনও সংস্করণ চান তবে অ্যারে-মুভ এই উত্তরটির নিকটতম, যদিও এটি একই বাস্তবায়ন নয়। আরও বিশদের জন্য এর ব্যবহার বিভাগটি দেখুন। এই উত্তরের পূর্ববর্তী সংস্করণ (যে পরিবর্তিত অ্যারে.প্রোটোটাইপ.মোভ) এনপিএম এ অ্যারে.প্রোটোটাইপ.মোভে পাওয়া যাবে ।


আমি এই ফাংশন দিয়ে মোটামুটি ভাল সাফল্য পেয়েছিলাম:

function array_move(arr, old_index, new_index) {
    if (new_index >= arr.length) {
        var k = new_index - arr.length + 1;
        while (k--) {
            arr.push(undefined);
        }
    }
    arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
    return arr; // for testing
};

// returns [2, 1, 3]
console.log(array_move([1, 2, 3], 0, 1)); 

নোট করুন যে শেষটি returnকেবল পরীক্ষার উদ্দেশ্যে হয়: spliceস্থানে অ্যারেতে অপারেশন সম্পাদন করে, সুতরাং কোনও রিটার্নের প্রয়োজন হয় না। এক্সটেনশান দ্বারা, moveএটি একটি স্থান-অপারেশন। আপনি যদি তা এড়াতে এবং অনুলিপি করতে চান তবে ব্যবহার করুন slice

কোড মাধ্যমে পদক্ষেপ:

  1. যদি new_indexঅ্যারের দৈর্ঘ্যের চেয়ে বড় হয়, আমরা চাই (নতুন আমি অনুমান করি) নতুন undefinedএস দিয়ে সঠিকভাবে অ্যারে প্যাড করব । আমাদের ছোট undefinedদৈর্ঘ্য না হওয়া পর্যন্ত এই ছোট্ট স্নিপেট অ্যারেটিতে চাপ দিয়ে এটি পরিচালনা করে ।
  2. তারপরে, arr.splice(old_index, 1)[0]আমরা পুরানো উপাদানটি ছড়িয়ে দেব। spliceছড়িয়ে দেওয়া উপাদানটি ফেরত দেয় তবে এটি একটি অ্যারেতে রয়েছে। আমাদের উপরের উদাহরণে, এটি ছিল [1]। সুতরাং আমরা সেই অ্যারের প্রথম সূচকটি 1সেখানে কাঁচা পেতে নিই ।
  3. তারপরে আমরা spliceএই উপাদানটি new_index এর জায়গায় toোকাতে ব্যবহার করি । যেহেতু আমরা উপরের অ্যারেটিকে প্যাড করেছি new_index > arr.length, সম্ভবত এটি সঠিক জায়গায় উপস্থিত হবে, যদি না তারা নেতিবাচক সংখ্যায় পাসের মতো অদ্ভুত কিছু করে থাকে।

নেতিবাচক সূচকগুলির জন্য অ্যাকাউন্টে ফ্যানসিয়ার সংস্করণ:

function array_move(arr, old_index, new_index) {
    while (old_index < 0) {
        old_index += arr.length;
    }
    while (new_index < 0) {
        new_index += arr.length;
    }
    if (new_index >= arr.length) {
        var k = new_index - arr.length + 1;
        while (k--) {
            arr.push(undefined);
        }
    }
    arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
    return arr; // for testing purposes
};
    
// returns [1, 3, 2]
console.log(array_move([1, 2, 3], -1, -2));

যা array_move([1, 2, 3], -1, -2)সঠিকভাবে মত জিনিসগুলির জন্য অ্যাকাউন্ট করা উচিত (শেষ উপাদানটিকে দ্বিতীয় স্থানে নিয়ে যাওয়া)। তার জন্য ফলাফল হওয়া উচিত [1, 3, 2]

উভয় ক্ষেত্রেই, আপনার মূল প্রশ্নে, আপনি কি করবেন array_move(arr, 0, 2)জন্য aপরে c। জন্য dসামনে b, আপনি কি করবেন array_move(arr, 3, 1)


19
এটি পুরোপুরি কাজ করে! এবং আপনার ব্যাখ্যা খুব পরিষ্কার। এটি লিখে সময় দেওয়ার জন্য ধন্যবাদ।
মার্ক ব্রাউন

16
আপনার অবজেক্ট এবং অ্যারে প্রোটোটাইপগুলি হেরফের করা উচিত নয়, উপাদানগুলির পুনরাবৃত্তি করার সময় এটি সমস্যার সৃষ্টি করে।
বুড়াক এমরে

9
@ বুড়ামেক্রে: আমার মনে হয় এতো পরিষ্কারভাবে সিদ্ধান্তে পৌঁছানো যায়নি। বেশিরভাগ ভাল জেএস প্রোগ্রামার (এবং সর্বাধিক জনপ্রিয় লাইব্রেরিগুলি) .hasOwnPropertyfor..in এর মতো জিনিসগুলির সাথে পুনরাবৃত্তি করার সময় একটি চেক ব্যবহার করবে , বিশেষত প্রোটোটাইপ এবং মওটুলের মতো লাইব্রেরি যা প্রোটোটাইপগুলিকে পরিবর্তন করে। যাইহোক, আমি অনুভব করিনি যে এটির তুলনামূলকভাবে সীমিত উদাহরণে এটি একটি বিশেষ গুরুত্বপূর্ণ সমস্যা এবং প্রোটোটাইপ পরিবর্তনটি একটি ভাল ধারণা কিনা তা নিয়ে সম্প্রদায়টিতে একটি দুর্দান্ত বিভাজন রয়েছে। সাধারণত, পুনরাবৃত্তির সমস্যাগুলি সবচেয়ে কম উদ্বেগ, যদিও though
রিড

3
পদক্ষেপ 1 এ লুপের প্রয়োজন নেই, আপনি কেবল ব্লকের this[new_index] = undefined;মধ্যে ব্যবহার করতে পারেন if। জাভাস্ক্রিপ্ট অ্যারেগুলি যেমন অল্প হয় তেমনি এটি কাজের জন্য new_index অন্তর্ভুক্ত করতে অ্যারের আকারকে প্রসারিত করবে .spliceতবে কোনও হস্তক্ষেপকারী উপাদান তৈরি করার প্রয়োজন ছাড়াই।
মাইকেল 11

3
@ মিশেল: ভাল পয়েন্ট - তবে করণটি সঠিক সূচকের আগে অ্যারে স্লটে this[new_index] = undefinedএকটি undefinedরাখবে । (যেমন, থাকবে স্লট 10 এবং যদি বিরলতা ঠিক আছে, বরং 9. স্লটে), আমরা কাজ করতে পারে অন্যান্য সংযুক্ত করান কল ছাড়া (এটিকে একটি যদি / অন্যথায় পরিবর্তে)। [1,2,3].move(0,10)1undefinedthis[new_index] = this.splice(old_index, 1)[0]
রিড

268

এখানে আমি জেএসপিফায় একটি লাইনার পেয়েছি ...

Array.prototype.move = function(from, to) {
    this.splice(to, 0, this.splice(from, 1)[0]);
};

যা পড়তে দুর্দান্ত but তবে আপনি যদি পারফরম্যান্স চান (ছোট ডেটা সেটগুলিতে) চেষ্টা করুন ...

 Array.prototype.move2 = function(pos1, pos2) {
    // local variables
    var i, tmp;
    // cast input parameters to integers
    pos1 = parseInt(pos1, 10);
    pos2 = parseInt(pos2, 10);
    // if positions are different and inside array
    if (pos1 !== pos2 && 0 <= pos1 && pos1 <= this.length && 0 <= pos2 && pos2 <= this.length) {
      // save element from position 1
      tmp = this[pos1];
      // move element down and shift other elements up
      if (pos1 < pos2) {
        for (i = pos1; i < pos2; i++) {
          this[i] = this[i + 1];
        }
      }
      // move element up and shift other elements down
      else {
        for (i = pos1; i > pos2; i--) {
          this[i] = this[i - 1];
        }
      }
      // put element from position 1 to destination
      this[pos2] = tmp;
    }
  }

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


2
আপনার আরও পারফরম্যান্ট সমাধান বড় ডেটাসেটের চেয়ে ধীর। jsperf.com/array-prototype-move/8
ডারউইন

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

3
@ রিড এটি কোনও প্রয়োজন ছিল না। আইএমও এটি ধরে নেওয়া ঠিক আছে যে অ্যারের দৈর্ঘ্য পরিবর্তন হয় না।
রোবস

3
একটি লাইন সমাধান দুটি পরিস্থিতি পরিচালনা করতে হবে:from >= to ? this.splice(to, 0, this.splice(from, 1)[0]) : this.splice(to - 1, 0, this.splice(from, 1)[0]);
রব এল

13
কখনও কখনও বিল্টিন প্রোটোটাইপগুলি কখনও সংশোধন করবেন না। nczonline.net/blog/2010/03/02/…
এলজেহার্ব

229

আমি এইভাবে পছন্দ করি। এটি সংক্ষিপ্ত এবং এটি কাজ করে।

function arraymove(arr, fromIndex, toIndex) {
    var element = arr[fromIndex];
    arr.splice(fromIndex, 1);
    arr.splice(toIndex, 0, element);
}

দ্রষ্টব্য: সর্বদা আপনার অ্যারে সীমা পরীক্ষা করতে মনে রাখবেন।

জেফিডেলে স্নিপেট চালান


29
যেহেতু অ্যারে.স্প্লাইস একটি নতুন অ্যারেতে মুছে ফেলা মান (গুলি) ফেরত দেয়, আপনি এটি ওয়ান লাইনার হিসাবে লিখতে পারেন ... arr.splice (সূচক + 1, 0, অ্যারি স্প্লাইস (সূচক, 1) [0]);
এরিক 19

49
ব্যক্তিগতভাবে আমি 3 লাইন কোড পছন্দ করি। এটি বোঝা সহজ: উপাদানটির একটি অনুলিপি পান; অ্যারে থেকে এটি অপসারণ; এটি একটি নতুন অবস্থানে .োকান। একটি লাইনার সংক্ষিপ্ত তবে অন্যান্য লোকেরা বুঝতে এটি এত স্পষ্ট নয় ...
ফিলিপ

2
সংক্ষিপ্ত এবং সহজ কোড। তবে এটি ২০১২ এর !!, অ্যারের একটি ক্লোন তৈরি করুন এবং অ্যারেটি পরিবর্তনের পরিবর্তে এটি ফিরিয়ে দিন। এটি আপনার ক্রিয়াকলাপটিকে "অ্যারেমেভ" ফাংশনাল প্রোগ্রামিং মানগুলিতে মেনে চলবে
স্যামওয়েলটারলি

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

36

স্প্লাইস () পদ্ধতিটি অ্যারের থেকে / থেকে আইটেমগুলি যুক্ত / সরিয়ে দেয় এবং সরানো আইটেম (গুলি) প্রদান করে।

দ্রষ্টব্য: এই পদ্ধতিটি মূল অ্যারে পরিবর্তন করে। / W3Schools /

Array.prototype.move = function(from,to){
  this.splice(to,0,this.splice(from,1)[0]);
  return this;
};

var arr = [ 'a', 'b', 'c', 'd', 'e'];
arr.move(3,1);//["a", "d", "b", "c", "e"]


var arr = [ 'a', 'b', 'c', 'd', 'e'];
arr.move(0,2);//["b", "c", "a", "d", "e"]

ফাংশনটি শৃঙ্খলাবদ্ধ হওয়ায় এটিও কাজ করে:

alert(arr.move(0,2).join(','));

এখানে ডেমো


এটি ব্যবহার করে এমন কোনও গ্রন্থাগার রয়েছে কি? বেশ ঝরঝরে!
4:25 এ ইউিকোডেড

এ সম্পর্কে অন্যান্য মন্তব্য দেখুন: অ্যারে এবং অবজেক্টের মতো বিল্ট-ইন প্রোটোটাইপগুলি সংশোধন করা খারাপ ধারণা। আপনি জিনিস ভাঙ্গবে।
জিওএডসিক

27

আমার 2 সি। পড়া সহজ, এটি কাজ করে, এটি দ্রুত, এটি নতুন অ্যারে তৈরি করে না।

function move(array, from, to) {
  if( to === from ) return array;

  var target = array[from];                         
  var increment = to < from ? -1 : 1;

  for(var k = from; k != to; k += increment){
    array[k] = array[k + increment];
  }
  array[to] = target;
  return array;
}

2
ফাংশনটির প্রথম স্ট্রিংয়ে আপনার ফিরে আসা উচিত array, যেমনটি এটি শেষে হয়েছিল done
সের্গেই ভোরোনজস্কি

3
সত্য আমি কীভাবে মিস করেছি? সংশোধন করা হয়েছে!
Merc

আমি আপনার সহজ এবং নমনীয় সমাধানটি সবচেয়ে পছন্দ করি। ধন্যবাদ!
রোমান এম কোস

18

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

({}) == ({}); // false

সোর্স অ্যারে এবং সোর্স, গন্তব্য সূচকগুলি গ্রহণ করে এমন ফাংশনটি এখানে। প্রয়োজনে আপনি এটিকে অ্যারে.প্রোটোটাইপে যুক্ত করতে পারেন।

function moveObjectAtIndex(array, sourceIndex, destIndex) {
    var placeholder = {};
    // remove the object from its initial position and
    // plant the placeholder object in its place to
    // keep the array length constant
    var objectToMove = array.splice(sourceIndex, 1, placeholder)[0];
    // place the object in the desired position
    array.splice(destIndex, 0, objectToMove);
    // take out the temporary object
    array.splice(array.indexOf(placeholder), 1);
}

1
এটি আশাব্যঞ্জক দেখাচ্ছে ... এবং আমি জাভাস্ক্রিপ্ট জেএস তুলনা সম্পর্কে জানি না। ধন্যবাদ!
মার্ক ব্রাউন

মামলায় কাজ করে না sourceIndex = 0,destIndex = 1
সের্গেই

destIndexউত্স উপাদান অ্যারের মধ্যে সরানো আগে সূচক বোঝানো হয়।
অনুরাগ

এটি এখন পর্যন্ত সেরা উত্তর। অন্যান্য উত্তরগুলি আমার স্যুটটিতে বেশ কয়েকটি ইউনিট পরীক্ষায় ব্যর্থ হয়েছিল (এগিয়ে চলমান বস্তু)
ইলিয়া ইভানভ

16

এটি @ রিডের সমাধানের ভিত্তিতে। ছাড়া:

  • আমি Arrayপ্রোটোটাইপ পরিবর্তন করছি না ।
  • কোনও আইটেমকে ডানদিকে undefinedসরিয়ে নিয়ে যাওয়া আইটেম তৈরি করে না , এটি আইটেমটিকে ডান-সর্বাধিক অবস্থানে নিয়ে যায়।

ফাংশন:

function move(array, oldIndex, newIndex) {
    if (newIndex >= array.length) {
        newIndex = array.length - 1;
    }
    array.splice(newIndex, 0, array.splice(oldIndex, 1)[0]);
    return array;
}

ইউনিট পরীক্ষা:

describe('ArrayHelper', function () {
    it('Move right', function () {
        let array = [1, 2, 3];
        arrayHelper.move(array, 0, 1);
        assert.equal(array[0], 2);
        assert.equal(array[1], 1);
        assert.equal(array[2], 3);
    })
    it('Move left', function () {
        let array = [1, 2, 3];
        arrayHelper.move(array, 1, 0);
        assert.equal(array[0], 2);
        assert.equal(array[1], 1);
        assert.equal(array[2], 3);
    });
    it('Move out of bounds to the left', function () {
        let array = [1, 2, 3];
        arrayHelper.move(array, 1, -2);
        assert.equal(array[0], 2);
        assert.equal(array[1], 1);
        assert.equal(array[2], 3);
    });
    it('Move out of bounds to the right', function () {
        let array = [1, 2, 3];
        arrayHelper.move(array, 1, 4);
        assert.equal(array[0], 1);
        assert.equal(array[1], 3);
        assert.equal(array[2], 2);
    });
});

এটি ভুল, আপনি যদি কোনও পোস্টের অবস্থান সন্নিবেশ করেন তবে আপনি যে আইটেমটি সরিয়ে রেখেছেন সেই
ইয়াও ঝাও

ধন্যবাদ. আমি নাল উপাদান ছাড়াই অ্যারে থেকে একটি আইটেম সরিয়ে ফেলতে চেয়েছিলাম (যা স্প্লাইস (ইনডেক্সটোরোমোভ) ব্যবহার করার সময় ঘটেছিল) আমি যে পদ্ধতিটি অ্যারের শেষে সরিয়ে নিতে চাইছিলাম তা সরানোর জন্য আমি আপনার পদ্ধতিটি ব্যবহার করেছি এবং তারপরে পপটি ব্যবহার করেছি () অপসারণ করার পদ্ধতি
লূক শোয়েেন

আমার আইটেমের জন্য দরকারী "আইটেমটিকে ডান-সর্বাধিক অবস্থানে নিয়ে যাওয়া" পছন্দ করেছে। thx
বিফুনক

11

Myচ্ছিক পরামিতি সহ এখানে আমার এক লাইনার ES6 সমাধানon

if (typeof Array.prototype.move === "undefined") {
  Array.prototype.move = function(from, to, on = 1) {
    this.splice(to, 0, ...this.splice(from, on))
  }
}

প্রস্তাবিত প্রথম সমাধানটির অভিযোজন digiguru

প্যারামিটার on এমন উপাদানগুলির সংখ্যা fromযা আপনি স্থানান্তর করতে চান।


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

7

একটি উপায় হ'ল স্লাইস পদ্ধতিটি ব্যবহার করে আপনি যে ক্রমটি চান তার সাথে টুকরোগুলি সহ একটি নতুন অ্যারে তৈরি করা হবে।

উদাহরণ

var arr = [ 'a', 'b', 'c', 'd', 'e'];
var arr2 = arr.slice(0,1).concat( ['d'] ).concat( arr.slice(2,4) ).concat( arr.slice(4) );
  • arr.slice (0,1) আপনাকে ['a'] দেয়
  • arr.slice (2,4) আপনাকে ['b', 'c'] দেয়
  • arr.slice (4) আপনাকে ['ই'] দেয়

1
আপনি বুঝতে পেরেছেন যে আপনার arr2শেষটি কনটেনটেশন অপারেশনের কারণে একটি স্ট্রিং হয়ে গেছে, তাই না? :) এটি সত্তা শেষ "adc,de"
কেন ফ্রাঙ্কোইরো

6

spliceপদ্ধতি Arrayযথাসাধ্য সাহায্য কর! https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice

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


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

@ মার্ক: স্ট্রিংটি স্প্লাইস করবেন না এবং এটি একই ভেরিয়েবলে সংরক্ষণ করবেন না, একটি নতুন স্ট্রিং তৈরি করুন এবং এটি বিছিন্ন করুন। আমার উত্তর নীচে দেখুন।
জারেড আপডেটিকে

6

আপনি কিছু বেসিক ক্যালকুলাস বাস্তবায়ন করতে পারেন এবং অ্যারে উপাদানকে এক অবস্থান থেকে অন্য স্থানে নিয়ে যাওয়ার জন্য সর্বজনীন ফাংশন তৈরি করতে পারেন।

জাভাস্ক্রিপ্টের জন্য এটি দেখতে এটির মতো দেখাচ্ছে:

function magicFunction (targetArray, indexFrom, indexTo) { 

    targetElement = targetArray[indexFrom]; 
    magicIncrement = (indexTo - indexFrom) / Math.abs (indexTo - indexFrom); 

    for (Element = indexFrom; Element != indexTo; Element += magicIncrement){ 
        targetArray[Element] = targetArray[Element + magicIncrement]; 
    } 

    targetArray[indexTo] = targetElement; 

}

বিস্তারিত ব্যাখ্যার জন্য "গ্লোমমেটার" এ "চলন্ত অ্যারে উপাদানগুলি" দেখুন।

http://www.gloommatter.com/DDesign/programming/moving-any-array-elements-universal-function.html


1
এটি সঠিক উত্তর হওয়া উচিত, কারণ এটি কোনও নতুন অ্যারে বরাদ্দ করে না। ধন্যবাদ!
সি

লিঙ্কটি নষ্ট হয়ে গেছে।
রোকিত

6

আমি এখানে এর উত্তর ECMAScript 6বন্ধ ভিত্তিতে একটি অপরিবর্তনীয় সমাধান কার্যকর করেছি @Merc:

const moveItemInArrayFromIndexToIndex = (array, fromIndex, toIndex) => {
  if (fromIndex === toIndex) return array;

  const newArray = [...array];

  const target = newArray[fromIndex];
  const inc = toIndex < fromIndex ? -1 : 1;

  for (let i = fromIndex; i !== toIndex; i += inc) {
    newArray[i] = newArray[i + inc];
  }

  newArray[toIndex] = target;

  return newArray;
};

ভেরিয়েবলের নামগুলি সংক্ষিপ্ত করা যেতে পারে, কেবলমাত্র দীর্ঘগুলি ব্যবহার করা যাতে কোডটি নিজেরাই ব্যাখ্যা করতে পারে।


অবশ্যই একটি ভাল উত্তর, মিউটেশনগুলি পার্শ্ব প্রতিক্রিয়া তৈরি করে
ম্যাট লো

1
কৌতূহলের বাইরে, কেন কেবল arrayতাত্ক্ষণিকভাবে ফিরে আসবেন না fromIndex === toIndex, এবং newArrayযদি এটি না হয় তবে কেবল তৈরি করুন ? অপরিচ্ছন্নতার অর্থ এই নয় যে কোনও পরিবর্তন নেই এমনকী ফাংশন কল অনুসারে একটি নতুন কপি তৈরি করতে হবে। এই ফাংশনের বর্ধিত দৈর্ঘ্যের জন্য কেবল বি / সি উদ্দেশ্য জিজ্ঞাসা করা (স্প্লাইস ভিত্তিক ওয়ান-লাইনারের তুলনায়) কর্মক্ষমতা এবং ব্যবহারের উপর নির্ভর করে fromIndexপ্রায়শই সমান হতে পারে toIndex
রবার্ট মনফেরা

5

আমার একটি অপরিবর্তনীয় সরানো পদ্ধতি দরকার (এটির যা মূল অ্যারে পরিবর্তন করে না), তাই আমি স্প্লাইসটি করার আগে অ্যারেটির একটি অনুলিপি তৈরির জন্য কেবল অবজেক্ট.সেসাইন ব্যবহার করার জন্য @ রিডের গৃহীত উত্তরটি আমি অভিযোজিত করেছি।

Array.prototype.immutableMove = function (old_index, new_index) {
  var copy = Object.assign([], this);
  if (new_index >= copy.length) {
      var k = new_index - copy.length;
      while ((k--) + 1) {
          copy.push(undefined);
      }
  }
  copy.splice(new_index, 0, copy.splice(old_index, 1)[0]);
  return copy;
};

এখানে এটি কার্যকরভাবে দেখায় একটি জিসফিল


পিপিএল বিবেচনায় রূপান্তর গ্রহণ করা দেখতে সর্বদা ভাল।
হুমান আসকারি

4
    Array.prototype.moveUp = function (value, by) {
        var index = this.indexOf(value),
            newPos = index - (by || 1);

        if (index === -1)
            throw new Error("Element not found in array");

        if (newPos < 0)
            newPos = 0;

        this.splice(index, 1);
        this.splice(newPos, 0, value);
    };

    Array.prototype.moveDown = function (value, by) {
        var index = this.indexOf(value),
            newPos = index + (by || 1);

        if (index === -1)
            throw new Error("Element not found in array");

        if (newPos >= this.length)
            newPos = this.length;

        this.splice(index, 1);
        this.splice(newPos, 0, value);
    };



    var arr = ['banana', 'curyWurst', 'pc', 'remembaHaruMembaru'];

    alert('withiout changes= '+arr[0]+' ||| '+arr[1]+' ||| '+arr[2]+' ||| '+arr[3]);
    arr.moveDown(arr[2]);


    alert('third word moved down= '+arr[0] + ' ||| ' + arr[1] + ' ||| ' + arr[2] + ' ||| ' + arr[3]);
    arr.moveUp(arr[2]);
    alert('third word moved up= '+arr[0] + ' ||| ' + arr[1] + ' ||| ' + arr[2] + ' ||| ' + arr[3]);

http://plnkr.co/edit/JaiAaO7FQcdPGPY6G337?p=preview


2

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

ছোট ছোট দূরত্বে চলমান বস্তুগুলি স্প্লাইস ব্যবহারের চেয়ে দ্রুততর (এক্স 10) দ্রুত চালিত হওয়ার সময় অন্য কয়েকটি পদ্ধতি ব্যবহার করা হয়েছিল। এটি অ্যারে দৈর্ঘ্যের উপর নির্ভর করে পরিবর্তিত হতে পারে তবে বড় অ্যারেগুলির জন্য এটি সত্য।

function ArrayMove(array, from, to) {
    if ( Math.abs(from - to) > 60) {
        array.splice(to, 0, array.splice(from, 1)[0]);
    } else {
        // works better when we are not moving things very far
        var target = array[from];
        var inc = (to - from) / Math.abs(to - from);
        var current = from;
        for (; current != to; current += inc) {
            array[current] = array[current + inc];
        }
        array[to] = target;    
    }
}

http://jsperf.com/arraymove-many-sizes


2

এটি অনেক জায়গায় বলা হয়েছে ( অ্যারে প্রোটোটাইপের সাথে কাস্টম ফাংশন যুক্ত করা ) অ্যারে প্রোটোটাইপের সাথে খেলানো একটি খারাপ ধারণা হতে পারে, যাইহোক আমি বিভিন্ন পোস্ট থেকে সেরাকে একত্রিত করেছি, আমি আধুনিক জাভাস্ক্রিপ্ট ব্যবহার করে এটি নিয়ে এসেছি:

    Object.defineProperty(Array.prototype, 'immutableMove', {
        enumerable: false,
        value: function (old_index, new_index) {
            var copy = Object.assign([], this)
            if (new_index >= copy.length) {
                var k = new_index - copy.length;
                while ((k--) + 1) { copy.push(undefined); }
            }
            copy.splice(new_index, 0, copy.splice(old_index, 1)[0]);
            return copy
        }
    });

    //how to use it
    myArray=[0, 1, 2, 3, 4];
    myArray=myArray.immutableMove(2, 4);
    console.log(myArray);
    //result: 0, 1, 3, 4, 2

আশা কারও কাজে লাগতে পারে


2

এই সংস্করণটি সমস্ত উদ্দেশ্যে আদর্শ নয়, এবং সকলেই কমা অভিব্যক্তি পছন্দ করে না, তবে এখানে একটি ওয়ান-লাইনার যা খাঁটি অভিব্যক্তি, একটি নতুন কপি তৈরি করে:

const move = (from, to, ...a) => (a.splice(to, 0, ...a.splice(from, 1)), a)

সামান্য পারফরম্যান্স-উন্নত সংস্করণ ইনপুট অ্যারে প্রদান করে যদি কোনও পদক্ষেপের প্রয়োজন হয় না, এটি অপরিবর্তনীয় ব্যবহারের জন্য এখনও ঠিক আছে, কারণ অ্যারেটি পরিবর্তন হবে না এবং এটি এখনও একটি শুদ্ধ অভিব্যক্তি:

const move = (from, to, ...a) => 
    from === to 
    ? a 
    : (a.splice(to, 0, ...a.splice(from, 1)), a)

উভয়ের প্রার্থনা

const shuffled = move(fromIndex, toIndex, ...list)

অর্থাত্ এটি একটি নতুন কপি তৈরি করতে ছড়িয়ে পড়ার উপর নির্ভর করে। একটি স্থির তাত্পর্য 3 ব্যবহার moveএকক অভিব্যক্তি সম্পত্তি, বা অ-ধ্বংসাত্মক প্রকৃতি, বা এর কার্যকারিতা বেনিফিটকে বিপদে ফেলবে splice। আবার, এটি এমন আরও উদাহরণ যা উত্পাদন ব্যবহারের পরামর্শের চেয়ে কিছু মানদণ্ড পূরণ করে।


1

Array.move.js

সারসংক্ষেপ

সরানো উপাদানগুলি সমন্বিত একটি অ্যারে প্রদান করে একটি অ্যারের মধ্যে উপাদানগুলি সরায়।

বাক্য গঠন

array.move(index, howMany, toIndex);

পরামিতি

সূচী : সূচি যাতে উপাদান সরানো যায়। নেতিবাচক হলে সূচক শেষ থেকে শুরু হবে।

HowMany : সূচী থেকে সরানোর উপাদানগুলির সংখ্যা ।

টু ইন্ডেক্স: সরানো উপাদানগুলি রাখার জন্য অ্যারের সূচক। নেতিবাচক হলে, টুআইন্ডেক্স শেষ থেকে শুরু হবে।

ব্যবহার

array = ["a", "b", "c", "d", "e", "f", "g"];

array.move(3, 2, 1); // returns ["d","e"]

array; // returns ["a", "d", "e", "b", "c", "f", "g"]

Polyfill

Array.prototype.move || Object.defineProperty(Array.prototype, "move", {
    value: function (index, howMany, toIndex) {
        var
        array = this,
        index = parseInt(index) || 0,
        index = index < 0 ? array.length + index : index,
        toIndex = parseInt(toIndex) || 0,
        toIndex = toIndex < 0 ? array.length + toIndex : toIndex,
        toIndex = toIndex <= index ? toIndex : toIndex <= index + howMany ? index : toIndex - howMany,
        moved;

        array.splice.apply(array, [toIndex, 0].concat(moved = array.splice(index, howMany)));

        return moved;
    }
});

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

1
a = ["এ", "বি", "সি"]; এ.মোভ (0,1,1); // এ = ["এ", "বি", "সি"], হওয়া উচিত ["বি", "এ", "সি"]
লিওনার্ড পাওলি

2
এই বৈশিষ্ট্যটি অপ্রচলিত এবং এটি আর সমর্থিত হতে পারে না। সাবধান থাকুন দেখুন: বিকাশকারী.মোজিলা.আর.ইন-
মোস্তফা

1

আমি @ রিডের সুন্দর উত্তরটি ব্যবহার করেছি , তবে অ্যারের প্রান্ত থেকে একটি উপাদানকে আরও একধাপ এগিয়ে নিয়ে যেতে শুরু করেছি - শুরুতে ( লুপের মতো )। যেমন ['ক', 'বি', 'সি'] কল করে ['সি', 'এ', 'বি'] হওয়া উচিত m

আমি new_index> = এই দৈর্ঘ্যের ক্ষেত্রে কেস পরিবর্তন করে এটি অর্জন করেছি।

Array.prototype.move = function (old_index, new_index) {
        console.log(old_index + " " + new_index);
        while (old_index < 0) {
            old_index += this.length;
        }
        while (new_index < 0) {
            new_index += this.length;
        }
        if (new_index >= this.length) {
            new_index = new_index % this.length;
        }
        this.splice(new_index, 0, this.splice(old_index, 1)[0]);
        return this; // for testing purposes
    };

1

রিডের দুর্দান্ত উত্তরের সংযোজন হিসাবে (এবং কারণ আমি মন্তব্য করতে পারি না); নেতিবাচক সূচক এবং খুব বড় সূচকগুলি "রোল ওভার" উভয় তৈরি করতে আপনি মডুলো ব্যবহার করতে পারেন:

function array_move(arr, old_index, new_index) {
  new_index =((new_index % arr.length) + arr.length) % arr.length;
  arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
  return arr; // for testing
}

// returns [2, 1, 3]
console.log(array_move([1, 2, 3], 0, 1)); 


হ্যাঁ - যেহেতু নেতিবাচক সূচকগুলি সমর্থিত, তাই আমার মতে অপরিজ্ঞাত মানগুলি সন্নিবেশ করানোর চেয়ে খুব বড় সূচকগুলি আবৃত করা বুদ্ধিমান বলে মনে হয়।
পাইথন 1981


1

আমি ভেবেছিলাম এটি একটি অদলবদল সমস্যা কিন্তু তা নয়। এখানে আমার ওয়ান-লাইনারের সমাধান:

const move = (arr, from, to) => arr.map((item, i) => i === to ? arr[from] : (i >= Math.min(from, to) && i <= Math.max(from, to) ? arr[i + Math.sign(to - from)] : item));

এখানে একটি ছোট পরীক্ষা:

let test = ['a', 'b', 'c', 'd', 'e'];
console.log(move(test, 0, 2)); // [ 'b', 'c', 'a', 'd', 'e' ]
console.log(move(test, 1, 3)); // [ 'a', 'c', 'd', 'b', 'e' ]
console.log(move(test, 2, 4)); // [ 'a', 'b', 'd', 'e', 'c' ]
console.log(move(test, 2, 0)); // [ 'c', 'a', 'b', 'd', 'e' ]
console.log(move(test, 3, 1)); // [ 'a', 'd', 'b', 'c', 'e' ]
console.log(move(test, 4, 2)); // [ 'a', 'b', 'e', 'c', 'd' ]
console.log(move(test, 4, 0)); // [ 'e', 'a', 'b', 'c', 'd' ]

ভাল, প্রশ্ন আইটেম অদলবদল সম্পর্কে ছিল না। লেখক একটি সন্নিবেশ কৌশলটির সমাধান চেয়েছিলেন।
আন্দ্রেয়াস ডলক

হাতে থাকা প্রশ্ন সম্পর্কে, এটি উদ্দেশ্যমূলকভাবে ভুল উত্তর।
বেন স্টুয়ার্ড

0
let ar = ['a', 'b', 'c', 'd'];

function change( old_array, old_index , new_index ){

  return old_array.map(( item , index, array )=>{
    if( index === old_index ) return array[ new_index ];
    else if( index === new_index ) return array[ old_index ];
    else return item;
  });

}

let result = change( ar, 0, 1 );

console.log( result );

ফলাফল:

["b", "a", "c", "d"]

0

    let oldi, newi, arr;
    
    if(newi !== oldi) {
      let el = this.arr.splice(oldi, 1);
      if(newi > oldi && newi === (this.arr.length + 2)) {
        this.arr.push("");
      }
      this.arr.splice(newi, 0, el);
      if(newi > oldi && newi === (this.arr.length + 2)) {
        this.arr.pop();
      }
    }


1
তাই আপনাকে স্বাগতম! 21 টি অতিরিক্ত উত্তর আছে ... সুতরাং, দয়া করে, শুধু কোড রাখবেন না। আপনার উত্তরের সুবিধা ব্যাখ্যা করুন।
ডেভিড গার্সিয়া বোদেগো

0

var ELEMS = ['a', 'b', 'c', 'd', 'e'];
/*
    Source item will remove and it will be placed just after destination
*/
function moveItemTo(sourceItem, destItem, elements) {
    var sourceIndex = elements.indexOf(sourceItem);
    var destIndex = elements.indexOf(destItem);
    if (sourceIndex >= -1 && destIndex > -1) {
        elements.splice(destIndex, 0, elements.splice(sourceIndex, 1)[0]);
    }
    return elements;
}
console.log('Init: ', ELEMS);
var result = moveItemTo('a', 'c', ELEMS);
console.log('BeforeAfter: ', result);


0

অ্যারে অনুলিপি ছাড়াই অপরিবর্তিত সংস্করণ:

const moveInArray = (arr, fromIndex, toIndex) => {
  if (toIndex === fromIndex || toIndex >= arr.length) return arr;

  const toMove = arr[fromIndex];
  const movedForward = fromIndex < toIndex;

  return arr.reduce((res, next, index) => {
    if (index === fromIndex) return res;
    if (index === toIndex) return res.concat(
      movedForward ? [next, toMove] : [toMove, next]
    );

    return res.concat(next);
  }, []);
};

0

আমি মনে করি সবচেয়ে ভাল উপায় অ্যারেগুলির জন্য একটি নতুন সম্পত্তি সংজ্ঞায়িত করা

Object.defineProperty(Array.prototype, 'move', {
    value: function (old_index, new_index) {
        while (old_index < 0) {
            old_index += this.length;
        }
        while (new_index < 0) {
            new_index += this.length;
        }
        if (new_index >= this.length) {
            let k = new_index - this.length;
            while ((k--) + 1) {
                this.push(undefined);
            }
        }
        this.splice(new_index, 0, this.splice(old_index, 1)[0]);
        return this;
    }
});

console.log([10, 20, 30, 40, 50].move(0, 1));  // [20, 10, 30, 40, 50]
console.log([10, 20, 30, 40, 50].move(0, 2));  // [20, 30, 10, 40, 50]

0

কোনও মিউটেশন ছাড়াই ES6 অ্যারে স্প্রেড অপারেটর ব্যবহার করে আর একটি খাঁটি জেএস বৈকল্পিক

const reorder = (array, sourceIndex, destinationIndex) => {
	const smallerIndex = Math.min(sourceIndex, destinationIndex);
	const largerIndex = Math.max(sourceIndex, destinationIndex);

	return [
		...array.slice(0, smallerIndex),
		...(sourceIndex < destinationIndex
			? array.slice(smallerIndex + 1, largerIndex + 1)
			: []),
		array[sourceIndex],
		...(sourceIndex > destinationIndex
			? array.slice(smallerIndex, largerIndex)
			: []),
		...array.slice(largerIndex + 1),
	];
}

// returns ['a', 'c', 'd', 'e', 'b', 'f']
console.log(reorder(['a', 'b', 'c', 'd', 'e', 'f'], 1, 4))
      
 


0

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

const move = (from, to, arr) => {
    to = Math.max(to,0)
    from > to 
        ? [].concat(
            arr.slice(0,to), 
            arr[from], 
            arr.filter((x,i) => i != from).slice(to)) 
        : to > from
            ? [].concat(
                arr.slice(0, from), 
                arr.slice(from + 1, to + 1), 
                arr[from], 
                arr.slice(to + 1))
            : arr}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.