1

I am trying to unscramble an array. The array has string items out of order with a number attached to specify what the order should be. I want to take the number within the array item and reassign the array item index to reflect that number. For example var scrambled = ["pizza4", "to2", "I0", "eat3", "want1"]. I have a function that searches the array for the number attached and returns the value. Now I want to take the value returned and turn it into the new item's index in a new array, like var unscrambled = []. This is what I have so far:

function unscramblePhrase() {
    var scrambled = ["pizza4", "to2", "I0", "eat3", "want1"];   
    var unscrambled = [];
    for (var counter = 0; counter < scrambled.length; counter++) {
        numPosition = scrambled[counter].search('[0-9]');
        arrayIndex = scrambled[counter].substring(numPosition);
        console.log(arrayIndex);
        unscrambled.push(scrambled[arrayIndex]);
    }
 console.log(unscrambled)
}

I see that my arrayIndex is pulling the numbers from the end of the scrambled array items but my attempt at assigning index position based off this variable is producing a newly scrambled array: ["want1", "I0", "pizza4", "eat3", "to2"].

6
  • 1
    What if the strings contain more than one number: "abc10def22"? What if there are strings with the same number: ["abc12", "def12"]? What if there is a missing number: ["abc0", "def3"] (2 is missing)? Commented Nov 14, 2018 at 17:00
  • @ibrahimmahrir was thinking the same. Obviously this is a very specific case. As OP mentioned, he already has a method for extracting the number from the string. Commented Nov 14, 2018 at 17:01
  • For the purpose of this example. assume that the array has all the correct numbers (0-4) and no duplicates. Commented Nov 14, 2018 at 17:01
  • What do you want as output? Commented Nov 14, 2018 at 17:02
  • I want it to read "I0 want1 to2 eat3 pizza4." Commented Nov 14, 2018 at 17:03

6 Answers 6

3

This is not the best way to sort an array, but your issue is that your using Array.prototype.push, when you should just be assigning the value to an index in unscrambled.

unscrambled[arrayIndex] = scrambled[counter];

But the real way to do this is with Array.prototype.sort

function getNum(str){
    return Number(str.substring(str.length -1));
}


unscrambled.sort((a, b) => getNum(a) - getNum(b));

Note: This method sorts your array in-place. This may be good, or not good depending on your requirements

But you can always use it on a clone:

[...unscrambled].sort((a, b) => getNum(a) - getNum(b));
Sign up to request clarification or add additional context in comments.

10 Comments

dont forget to instantiate the unscrambled array first like unscrambled = new Array(scrambled.length);
no this can create reference issues as the array has to grow dynamicaly during assignment which is not supported to work by all browsers, instead instantaiate it with the correct size before-hand
@NikosM. What browsers don't support dynamically growing arrays?
@dovidweisz, actually no browsers supports dynamicaly growing an array by random assignment to one index position. What is done is that the index is added as dynamic property in the array object and not as array index per se. Anyway details, better to instatiate the whole array since the size is known and THEN any index is indeed available for assignment NOT simply adding dynamic properties in the object
@NikosM. If what you're saying is true, we can verify it by checking array.length.
|
3

You could simplify this by using RegEx to split the array into value and index, sort them, and then remove the additional information using a secondary .map to return the string array.

scrambled.map(i => 
[i.replace(/\d/g,""), +i.replace(/\D/g,"")])
.sort((a, b) => a[1] - b[1])).map(i => i[0]);

var scrambled = ["pizza4", "to2", "I0", "eat3", "want1"];   

var unscrambled = scrambled.map(i => 
  [i.replace(/\d/g,""), +i.replace(/\D/g,"")])
  .sort((a, b) => a[1] - b[1])
  .map( i => i[0]);

console.log(unscrambled);

3 Comments

Why use Array.from on an array (new array, not the original)?
Obviously an excellent answer, but I think it will not be great for OP because it seems like he is still learning JS, and this is a pretty fancy ES6 snippet. Either way, very nice.
@SamCreamer thanks! It looks fancy admittedly, but it's actually rather simple. I think being shown code that is maybe a little intimidating is a good thing, as it teaches you new techniques and patterns.
1

Try this (no clue if it works):

function unscramblePhrase() { var scrambled = ["pizza4", "to2", "I0", "eat3", "want1"];
var unscrambled = []; for (var counter = 0; counter < scrambled.length; counter++) { numPosition = scrambled[counter].search('[0-9]'); arrayIndex = scrambled[counter].substring(numPosition); console.log(arrayIndex); unscrambled[arrayIndex] = scrambled[counter]; } console.log(unscrambled) }

Comments

1

You can attempt with "Array.sort" as well like below

var scrambled = ["pizza4", "to2", "I0", "eat3", "want1"]

let getNumberIndex = (d) => [...d].findIndex(v => Number.isInteger(+v))

let getNumber = (d) => d.slice(getNumberIndex(d))

let unscrambled = scrambled.slice(0).sort((a,b) => getNumber(a) - getNumber(b))

console.log(unscrambled)

Comments

1
const words = ["I0", "want1", "to2", "eat3", "pizza4"]

words
    .map (w => parseInt (w [--w.length]))
    .sort ()
    .map (i => words.filter (w => w [--w.length] == i) [0].replace (i, ''))

// ["I", "want", "to", "eat", "pizza"]

Comments

1

You could take a single loop and take the parts of the string and the index, assign the value to the index and return the array.

var scrambled = ["pizza4", "to2", "I0", "eat3", "want1"],
    result = scrambled.reduce((r, string) => {
        var [s, i] = string.match(/\D+|\d+/g);
        r[i] = s;
        return r;
    }, []);
    
console.log(result);

More fun with objects.

var scrambled = ["pizza4", "to2", "I0", "eat3", "want1"],
    result = Object.assign(
        [],
        ...scrambled.map(s => (([v, k]) => ({ [k]: v }))(s.match(/\D+|\d+/g)))
    );
    
console.log(result);

1 Comment

Nice answer! As silly as it may sound I was completely unaware that you could assign to any index in an array before the array was formed!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.