scoutpout326
scoutpout326

Reputation: 13

JavaScript: reorder array based on numbers within array items

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"].

Upvotes: 1

Views: 240

Answers (6)

Nina Scholz
Nina Scholz

Reputation: 386786

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

Upvotes: 1

user10616833
user10616833

Reputation:

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"]

Upvotes: 1

dovidweisz
dovidweisz

Reputation: 1234

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

Upvotes: 3

Nitish Narang
Nitish Narang

Reputation: 4184

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)

Upvotes: 1

zfrisch
zfrisch

Reputation: 8670

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

Upvotes: 3

Sam Creamer
Sam Creamer

Reputation: 5361

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

Upvotes: 1

Related Questions