Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scramble String According to Array Values - Javascript

Trying to solve this question on Codewars.

I've seen other articles that deal with shuffling / scrambling a string randomly.

But what about scrambling a string according to the values in a given array?

I.e. abcd given the array [0, 3, 2, 1] will become acdb because:

  • a moves to index 0
  • b moves to index 3
  • c moves to index 2
  • d moves to index 1

My guess is to start out by splitting the string into an array. And then we want to get the index value of the array that's passed into the scramble function, and push the character at the index value from that array into the new array. And finally join the array:

function scramble(str, arr) {

  let newArray = str.split("");
  let finalArray = [];

  for (let i = 0; i < str.length; i++) {
    console.log(newArray);
    finalArray.push(newArray.splice(arr[i], 1));
  }
  return finalArray;
}

console.log(scramble("abcd", [0, 3, 1, 2]));

But the problem with this logic is that .splice() removes the character from the newArray every time.

Is there another method that will remove the character at the specified index without modifying the original array?

I don't think slice will work either.

like image 978
HappyHands31 Avatar asked Jun 03 '19 21:06

HappyHands31


3 Answers

You can make a separate array to store the letters.

var str = "abcd";
var arr = [0, 3, 2, 1];
function scramble(s, a) {
    var ar = Array(a.length);
    a.forEach((e, i) => {
        ar[e] = s[i];
    });
    return ar.join('');
}
console.log(scramble(str, arr));
like image 94
Yousername Avatar answered Nov 15 '22 00:11

Yousername


Answer

Use reduce on the array and as the array is iterated assign the character of the iterator index(i) in the string(s) to the value index(v) of the new array(ra). After the reduce completes, use join to turn the returned array(ra) back into a string.

let scramble = (s, a) => a.reduce((ra,v,i)=> (ra[v] = s[i], ra), []).join("");

Example:

let scramble = (s, a) => a.reduce((ra,v,i)=> (ra[v] = s[i], ra), []).join("");

console.log( scramble("abcd", [0,3,2,1]) );

Clarification Code:

I realize the above code may be hard to wrap your head around. Let me provide you with the same exact functionality, but in a standard function. Keep in mind this is exactly what is happening in the above code, but it may be simpler to comprehend if you're not used to the concision of ES6:

function scramble(my_string, my_array) { 
   // create an array to return
   let returnable_array = [];

   // loop through the provided array. 
   // string index is the array key: 0,1,2,3
   // array_index is the value of the array keys: 0,3,2,1

   for(let [string_index, array_index] of my_array.entries()) {

   // we assign the character at string index 
   // to the value index inside the returnable array

    returnable_array[array_index] = my_string[string_index];
   } 

   // we turn the array into a string
   let returnable_string = returnable_array.join("");

   // we return the string
   return returnable_string
}

Example:

    function scramble(my_string, my_array) { 
       let returnable_array = [];
       for(let [string_index, array_index] of my_array.entries()) {
        returnable_array[array_index] = my_string[string_index];
       } 
       returnable_string = returnable_array.join("");
       return returnable_string
    }


console.log(scramble("abcd", [0,3,1,2]));
like image 36
zfrisch Avatar answered Nov 15 '22 01:11

zfrisch


You can loop over the input string get the character at the current position using string.charAt(position) and put it into a new array into the position retrieved from the positions array.

function scramble (str, arr) {
let newArray = [];
for (let i = 0; i < str.length; i++) {
    newArray[arr[i]]=str.charAt(i);
  }
  return newArray.join();
}

console.log(scramble("abcd", [0, 3, 1, 2]));
like image 25
obscure Avatar answered Nov 15 '22 00:11

obscure