एक सरणी तत्व को एक सरणी स्थिति से दूसरे स्थान पर ले जाएं


522

मुझे एक कठिन समय पता चल रहा है कि कैसे एक सरणी तत्व को स्थानांतरित करना है। उदाहरण के लिए, निम्नलिखित दिए गए हैं:

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

मैं स्थानांतरित करने के लिए एक समारोह कैसे लिख सकते हैं 'd'इससे पहले कि 'b'?

या 'a'बाद में 'c'?

इस कदम के बाद, बाकी तत्वों के सूचकांक को अपडेट किया जाना चाहिए। चाल गिरफ्तार [0] = 'क', गिरफ्तारी [1] = 'घ' गिरफ्तारी [2] = 'ख', गिरफ्तारी [3] = 'ग', गिरफ्तारी [4] = के बाद पहले उदाहरण में इसका मतलब है 'इ'

ऐसा लगता है कि यह बहुत आसान होना चाहिए, लेकिन मैं इसके चारों ओर अपना सिर नहीं लपेट सकता।


3
अच्छी तरह से यह सवाल पुराना है, लेकिन सोना
जलाल

ES6 का उपयोग करconst changeValuePosition = (arr, init, target) => {[arr[init],arr[target]] = [arr[target],arr[init]]; return arr}
muhsalaa

यह बस तत्वों को स्वैप करता है initऔर target
मैट एफ

जवाबों:


671

यदि आप npm पर एक संस्करण चाहते हैं, तो सरणी-चाल इस उत्तर के सबसे करीब है, हालांकि यह समान कार्यान्वयन नहीं है। अधिक जानकारी के लिए इसका उपयोग अनुभाग देखें। इस उत्तर का पिछला संस्करण (जो कि Array.prototype.move को संशोधित करता है) npm पर array.prototype.move पर पाया जा सकता है ।


मुझे इस समारोह में काफी अच्छी सफलता मिली:

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सरणी की लंबाई से अधिक है, तो हम नए undefineds के साथ सरणी को ठीक से पैड करने के लिए (मुझे अनुमान है) चाहते हैं । undefinedजब तक हमारे पास उचित लंबाई न हो, तब तक यह थोड़ा स्निपेट एरे पर धकेल कर इसे संभालता है ।
  2. फिर, arr.splice(old_index, 1)[0]हम पुराने तत्व को अलग करते हैं। spliceउस तत्व को लौटाता है जिसे बाहर निकाला गया था, लेकिन यह एक सरणी में है। हमारे उपरोक्त उदाहरण में, यह था [1]। तो हम कच्चे पाने के लिए उस सरणी का पहला सूचकांक लेते हैं 1
  3. फिर हम spliceइस तत्व को new_index के स्थान पर सम्मिलित करने के लिए उपयोग करते हैं । चूँकि हमने ऊपर दिए गए सरणी को गद्देदार किया है 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)लिए करेंगे । के लिए पहले , आप क्या करेंगे ।acdbarray_move(arr, 3, 1)


19
यह पूरी तरह से काम करता है! और आपका स्पष्टीकरण बहुत स्पष्ट है। इसे लिखने के लिए समय निकालने के लिए धन्यवाद।
मार्क ब्राउन

16
आपको ऑब्जेक्ट और एरियर प्रोटोटाइप में हेरफेर नहीं करना चाहिए, यह तत्वों की पुनरावृत्ति होने पर समस्याओं का कारण बनता है।
बुरक इमरे

9
@burakemre: मुझे लगता है कि निष्कर्ष इतने स्पष्ट रूप से नहीं पहुंचा है। सबसे अच्छा JS प्रोग्रामर (और सबसे लोकप्रिय लाइब्रेरी) एक .hasOwnPropertyचेक का उपयोग करेंगे जब for..in जैसी चीजों के साथ पुनरावृत्ति होती है, विशेष रूप से प्रोटोटाइप और MooTools जैसी लाइब्रेरी के साथ जो प्रोटोटाइप को संशोधित करते हैं। वैसे भी, मुझे नहीं लगा कि यह इस तरह के अपेक्षाकृत सीमित उदाहरण में एक विशेष रूप से महत्वपूर्ण मुद्दा था, और प्रोटोटाइप संशोधन एक अच्छा विचार है या नहीं, इस समुदाय में एक अच्छा विभाजन है। आम तौर पर, पुनरावृत्ति समस्याएं कम से कम चिंता का विषय हैं, हालांकि।
रीड

3
चरण 1 में लूप की कोई आवश्यकता नहीं है, आप बस ब्लॉक के this[new_index] = undefined;भीतर उपयोग कर सकते हैं if। के रूप में जावास्क्रिप्ट सरणियों विरल हैं यह .spliceकार्य करने के लिए new_index को शामिल करने के लिए सरणी आकार का विस्तार करेगा, लेकिन किसी भी हस्तक्षेप करने वाले तत्वों को बनाने की आवश्यकता के बिना।
माइकल

3
@ मिचेल: अच्छी बात है - लेकिन this[new_index] = undefinedवास्तव में सही इंडेक्स से पहले यह undefinedएक सरणी स्लॉट में डाल देगा । (उदाहरण के लिए, होगा स्लॉट 10 में और अगर विरल ठीक है, बल्कि 9. स्लॉट में), हम कर सकते थे अन्य जोड़ कॉल के बिना (यह एक अगर / किसी और के बजाय)। [1,2,3].move(0,10)1undefinedthis[new_index] = this.splice(old_index, 1)[0]
रीड

268

यहाँ एक लाइनर मुझे JSPerf पर मिला है ...।

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

जो पढ़ने के लिए बहुत बढ़िया है, लेकिन यदि आप प्रदर्शन (छोटे डेटा सेट में) चाहते हैं, तो प्रयास करें ...

 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
यह वास्तव में मूर्खतापूर्ण व्यापार की तरह लगता है। छोटे डेटा सेट पर प्रदर्शन एक नगण्य लाभ है, लेकिन बड़े डेटा सेट पर नुकसान एक महत्वपूर्ण नुकसान है। आपका नेट एक्सचेंज नकारात्मक है।
Kyeotic

3
@ वह आवश्यकता नहीं थी। IMO यह मानना ​​ठीक है कि सरणी की लंबाई संशोधित नहीं होती है।
रोज़बेक

3
एक पंक्ति के समाधान के लिए दो स्थितियों को संभालने की आवश्यकता होती है:from >= to ? this.splice(to, 0, this.splice(from, 1)[0]) : this.splice(to - 1, 0, this.splice(from, 1)[0]);
Rob L

13
कृपया कभी भी बिलियन प्रोटोटाइप को संशोधित न करें। nczonline.net/blog/2010/03/02/...
LJHarb

229

मुझे यह तरीका पसंद है। यह संक्षिप्त है और यह काम करता है।

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

नोट: हमेशा अपनी सरणी सीमा की जांच करना याद रखें।

स्निपेट को jsFiddle पर चलाएं


29
चूंकि Array.splice एक नए Array में हटाए गए मान को लौटाता है, आप इसे एक लाइनर के रूप में लिख सकते हैं ... arr.splice (इंडेक्स + 1, 0, arr.splice (इंडेक्स, 1) [0]);
एरिक

49
व्यक्तिगत रूप से मैं 3 लाइन कोड पसंद करता हूं। यह समझना आसान है: तत्व की एक प्रति प्राप्त करें; इसे सरणी से हटा दें; इसे एक नई स्थिति में डालें। एक लाइनर कम है, लेकिन अन्य लोगों को समझने के लिए इतना स्पष्ट नहीं है ...
फिलिप

2
संक्षिप्त और सरल कोड। लेकिन यह 2019 है !!, सरणी का एक क्लोन बनाएं और सरणी को बदलने के बजाय इसे वापस लौटाएं। यह आपके फ़ंक्शन को "arraymove" कार्यात्मक प्रोग्रामिंग मानकों का पालन करेगा
SamwellTarly

4
ठीक नहीं बल्कि सब कुछ न है और न ही हो गया है कार्यात्मक प्रोग्रामिंग अनुरूप; इसके अलावा यह स्थानीय सरणियों में हेरफेर करने के लिए एक प्रक्रिया के अंदर कार्यात्मक प्रोग्रामिंग में उपयोगी हो सकता है।
स्टेकऑवरफ्लो

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(','));

यहां डेमो करें


क्या कोई पुस्तकालय है जो इसका उपयोग करता है? काफी साफ़!
यूसीकोड

इसके बारे में अन्य टिप्पणियाँ देखें: यह एक खराब विचार है जिसमें अंतर्निहित प्रोटोटाइप जैसे एरे और ऑब्जेक्ट को संशोधित करना है। आप चीजों को तोड़ देंगे।
भू

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, क्योंकि यह अंत में किया गया था।
सेर्गेई वोरोनेज़स्की

3
यह सच है कि मैं कैसे याद किया? फिक्स्ड!
मर्क

मुझे आपका सरल और लचीला समाधान सबसे ज्यादा पसंद है। धन्यवाद!
रोमन एम। कोस

18

सरणी के आकार को स्थिर रखने के लिए ले जाने वाले आइटम के स्थान पर किसी चीज़ को धकेलने के @Reid से इस विचार को प्राप्त करें। यह गणना को सरल करता है। इसके अलावा, किसी खाली वस्तु को धकेलने के अतिरिक्त फायदे हैं, जो बाद में उसके लिए खोज करने में सक्षम हैं। यह तब तक काम करता है क्योंकि दो वस्तुएं तब तक समान नहीं होती हैं जब तक वे एक ही वस्तु का संदर्भ नहीं दे रही हैं।

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

तो यहाँ फ़ंक्शन है जो स्रोत सरणी, और स्रोत, गंतव्य अनुक्रमित में लेता है। यदि आवश्यक हो तो आप इसे Array.prototype में जोड़ सकते हैं।

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
यह आशाजनक लग रहा है ... और मुझे नहीं पता था कि जावास्क्रिप्ट js तुलना के बारे में। धन्यवाद!
मार्क ब्राउन

मामले के लिए काम नहीं करता है 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
bFunc

11

यहाँ एक वैकल्पिक पैरामीटर के साथ मेरा एक लाइनर 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
यह सही उत्तर होना चाहिए, क्योंकि यह किसी भी नए सरणियों को आवंटित नहीं करता है। धन्यवाद!
C

लिंक टूट गया है।
Rokit

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;
};

यहाँ एक jsfiddle यह कार्रवाई में दिखा रहा है


पीपीएल को म्यूटेशन को ध्यान में रखते हुए देखना हमेशा अच्छा होता है।
होमन आस्करी

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

मैंने छोटी और बड़ी दोनों दूरियों को आगे बढ़ाते हुए इनमें से दो को थोड़ा बेहतर काम करने के लिए जोड़ा। मुझे काफी सुसंगत परिणाम मिलते हैं, लेकिन यह संभवत: किसी के द्वारा मुझसे अलग आकार के लिए अलग तरीके से काम करने के लिए होशियार होने से थोड़ा कम किया जा सकता है।

कुछ अन्य तरीकों का उपयोग करते समय, वस्तुओं को स्थानांतरित करना छोटी दूरी (x10) के बंटवारे का उपयोग करने से काफी तेज था। यह सरणी की लंबाई के आधार पर बदल सकता है, लेकिन यह बड़े सरणियों के लिए सही है।

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

यह कई स्थानों (में कहा गया है Array.prototype में कस्टम कार्यों जोड़ने ) सरणी प्रोटोटाइप के साथ खेल रहा है एक बुरा विचार हो सकता है, वैसे भी मैं विभिन्न पदों से सबसे अच्छा संयुक्त, मैं आधुनिक जावास्क्रिप्ट का उपयोग कर इस के साथ आया था,:

    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 : तत्वों की संख्या सूचकांक से स्थानांतरित करने के लिए ।

theIndex : सरणी का सूचकांक जिसमें स्थानांतरित तत्वों को रखना है। यदि नकारात्मक है, तो इंडेक्स अंत से शुरू होगा।

प्रयोग

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 = ["a", "b", "c"]; a.move (0,1,1); // a = ["a", "b", "c"], होना चाहिए ["b", "a", "c"]
लियोनार्ड पाउली

2
यह सुविधा अप्रचलित है और इससे कोई समर्थन नहीं मिल सकता है। सावधान रहें देखें: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
मुस्तफा

1

मैंने @Reid के अच्छे उत्तर का उपयोग किया , लेकिन एक एरे के अंत से एक तत्व को एक कदम आगे ले जाने के साथ संघर्ष किया - शुरुआत से (जैसे लूप में )। जैसे ['a ’,' b’, 'c ’] बन जाना चाहिए [, c’, a a ’,' b] को बुलाकर। move (2,3)।

मैंने new_index> = this.length के लिए मामला बदलकर इसे हासिल किया।

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)); 


हां - चूंकि नकारात्मक सूचकांकों का समर्थन किया जाता है, इसलिए मेरी राय में अपरिभाषित मूल्यों को सम्मिलित करने के बजाय बहुत बड़े सूचकांकों को लपेटना समझदारी है।
python1981


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

मुझे लगता है कि सबसे अच्छा तरीका है Arrays के लिए एक नई संपत्ति परिभाषित करना

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

ईएस 6 सरणी का उपयोग करने वाला एक और शुद्ध जेएस संस्करण बिना किसी उत्परिवर्तन के साथ ऑपरेटर फैलाता है

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}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.