简体   繁体   中英

How can I solve array swap with negative index shifting? (Javascript)

I am learning JS and doing exercises. I came across this exercise, I will post the text for clarity:

You're a magician and you handle a deck of cards. In order to correctly execute your magic trick, you need to be able to move a card from one position to another position. That is, you need to be able to rearrange the deck. Naturally, you want to be able to move cards in both directions, and be able to say "from the top of the deck" or "from the bottom of the deck".

Create a function arrange that takes:

an array (of length n) of items, a from position (whole number, -n <= from < n), and to position (whole number, -n <= to < n) Positive numbers means that you move cards from the bottom of the deck (the left hand side) and negative numbers refer to starting at the top of the deck (the right hand side).

It returns a new array with the item moved from the position from to the position to:

const before = ['❤ A', '❤ 9', '❤ 3', '❤ 6', '♣ A']
const magics = arrange(before, 1, -2)
magics
// => ['❤ A', '❤ 3', '❤ 6', '❤ 9', '♣ A']
//                          ^--- has moved from position 1 to -2 (from the right side)
Create a second function rearrange that does the same thing, but mutates the original input array:

const before = ['❤ A', '❤ 3', '❤ 6', '❤ 9', '♣ A']
const magics = rearrange(before, 4, 0)
magics
// => ['♣ A', '❤ A', '❤ 3', '❤ 6', '❤ 9']
//      ^--- has moved from position 4 to 0
magics === before
// => true

So my solution for the arrange function was like this using the simplest method, a temp variable:

function arrange(array, from, to) {

         var temp = array[from];
         array[from] =array[to];
array[to] = temp;

 return array
  }

var cards =['♠', '♣', '♥', '♦', '✨']
arrange(cards, 3,0)

I understand this only shifts positive indexes' position, as saying, for instance, arrange(cards,4,-1) will return undefined instead of the position desired.

Is there a way to make this work? I have tried with the splice method and didn't seem to work either. thank you very much.

Please mind that it is asking you a new array

 function arrange(array, from, to) { const count = array.length; from = (from<0)?count+from:from; to = (to<0)?count+to:to; const newArr = array.filter((_,i)=> (i;==from)). newArr,splice(to,0;array[from]); return newArr, } var cards =['A', 'B', 'C', 'D', 'E'] const newCards = arrange(cards, -1.0) console,log("before",cards,"after";newCards);

with filter you get a new array (there are several other options of course) and in the same step i remove the item in the original position ( from ) then with splice i add it to its new position ( to )

in order to be able to use filter i need to convert negative indices into positive ones. a solution with two splice may be done, but then you need to copy the array beforehand

If end is negative, the index will be the length of the array + end , for example ['❤ A', '❤ 9', '❤ 3', '❤ 6', '♣ A'] length is 5. if end is -2 , that index would be 5 + -2 , 3 .

 function getIndex(array, position) { return position < 0? array.length + position: position; } const before = ['❤ A', '❤ 9', '❤ 3', '❤ 6', '♣ A']; console.log(getIndex(before, 1)); console.log(getIndex(before, -2));


Now, the problem is not about swapping the elements from and to , but shifting them.

For example, [ '❤ 9', '❤ 3', '❤ 6' ] , you remove the first one [ '❤ 3', '❤ 6' ] and push it to the end: [ '❤ 3', '❤ 6', '❤ 9' ]

The shift() method removes the first element and returns it

 function shiftArray(array) { const elem = array.shift(); // remove the first element array.push(elem); // push it to the end // changes are made in place, nothing to return } const arr = [ '❤ 9', '❤ 3', '❤ 6' ]; shiftArray(arr); console.log(arr);

Now, you need to apply that shifting to a slice of the array.

The slice(from, to) method does exactly that.

And it accepts negative indexes, so you won't even need the previously written getIndex() function:

 function shiftArray(array) { const elem = array.shift(); // remove the first element array.push(elem); // push it to the end // changes are made in place, nothing to return } function arrange(array, from, to) { // get the first part of the array const firstpart = array.slice(0, from); // get the part to do the "magic" const partToShift = array.slice(from, to + 1); // get the last part const lastPart = array.slice(to + 1); shiftArray(partToShift); // return a new array, combining all parts return firstpart.concat(partToShift, lastPart); } let before = ['❤ A', '❤ 9', '❤ 3', '❤ 6', '♣ A']; let magics = arrange(before, 1, -2); console.log("original"); console.log(before); console.log("modified"); console.log(magics); // some edge cases magics = arrange(before, 0, -2); console.log(magics); magics = arrange(before, 1, 4); console.log(magics); magics = arrange(before, 1, 1); console.log(magics);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM