0

It's a bit of a tricky situation I'm in, but I have an array like this:

const nums = [32, -3, 62, 8, 121, -231, 62, 13];

and need to replace them by their corresponding ascending index. The above example should yield:

[4, 1, 5, 2, 7, 0, 6, 3]

The solution I've come up with is this: TS Playground

const nums = [32, -3, 62, 8, 121, -231, 62, 13];
const numsCopy = nums.map(e => e);

// Basic sorting
for (let i = 0; i < numsCopy.length; i++) {
    for (let j = 0; j < numsCopy.length; j++) {
        if (numsCopy[i] < numsCopy[j]) {
            let t = numsCopy[j];
            numsCopy[j] = numsCopy[i];
            numsCopy[i] = t;
        }
    }
}

for (let i = 0; i < numsCopy.length; i++) {
    let sortedValue = numsCopy[i];

    nums[nums.indexOf(sortedValue)] = i;
}

Problems arise however when I change nums to include a value nums.length > n >= 0. The call nums.indexOf(...) may return a faulty result, as it may have already sorted an index, even though it exists somewhere in the array.

If you replace nums with these values, -231 will have an index of 2 for some reason...

const nums = [32, -3, 62, 7, 121, -231, 62, 13, 0];

> [5, 1, 6, 3, 8, 2, 7, 4, 0]

Is there a better approach to this problem, or a fix to my solution?

Herbie Vine
  • 1,643
  • 3
  • 17
  • 32
  • Isn't the answer `5,1,3,7,0,2,6,4` and not `4,1,5,2,7,0,6,3`? Maybe I just don't understand what you mean by "replace them by their corresponding ascending index" – Andrew Parks Feb 18 '23 at 17:04
  • why do you need to do this? what's the use case? is this homework? – szaman Feb 18 '23 at 17:07
  • If you do `nums.sort()`, you get your array sorted in ascending order right? The 1st element will be `-231`, 2nd will be `-3`, etc... And with that data, I'd want to replace their values in `nums` by their respective index in this sorted array. – Herbie Vine Feb 18 '23 at 17:10
  • Does this answer your question? [Javascript: Sort array and return an array of indices that indicates the position of the sorted elements with respect to the original elements](https://stackoverflow.com/questions/3730510/javascript-sort-array-and-return-an-array-of-indices-that-indicates-the-positio) – Dexygen Feb 18 '23 at 18:10
  • No, they are very similar though. It's a little hard to explain, but I think I did a better job in the comments of the first answer :) – Herbie Vine Feb 18 '23 at 18:27

2 Answers2

2

You could sort the indices by the value and create a new array with index values a sorted positions.

to get the wanted result call the sorting function again and you get the indices sorted by the index order.

const
    sort = array => [...array.keys()].sort((a, b) => array[a] - array[b]),
    fn = array => sort(sort(array));

console.log(...fn([32, -3, 62, 8, 121, -231, 62, 13])); // 4 1 5 2 7 0 6 3
console.log(...fn([-1, 3, 1, 0, 2, 9, -2, 7])); // 1 5 3 2 4 7 0 6
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Actually this doesn't seem to work in some cases. See this TS Playground: https://pastebin.com/zBPGcy1X – Herbie Vine Feb 18 '23 at 17:33
  • what is wrong`? – Nina Scholz Feb 18 '23 at 17:53
  • 1
    It's a duplicate anyway: https://stackoverflow.com/questions/3730510/javascript-sort-array-and-return-an-array-of-indices-that-indicates-the-positio/54323161#54323161 – Dexygen Feb 18 '23 at 18:11
  • No, it's not the same question. I do not want their index in the array instance, I want it as if they were in ascending order. So if I take the first array you provided in your example: The value `-231` should map, at the same index that `-231` occupied, to 0, as it is the 0th element, in the ascending order, in the list. – Herbie Vine Feb 18 '23 at 18:25
  • Sorry, this problem is a little unorthodox, but I'm very grateful for the help you've provided :). I hope the above explanation makes things a little clearer.... – Herbie Vine Feb 18 '23 at 18:26
  • @HerbieVine, i have no idea what is going wrong. – Nina Scholz Feb 18 '23 at 18:27
  • Well the index of -231 in the original array is 5 right? The new array should also have, at index 5, the value of 0. If the sort the array in ascending order, we get this: [-231, -3, 8, 13, 32, 62, 121]. -231 maps to 0. 121 to 6. – Herbie Vine Feb 18 '23 at 18:30
1

Copy the array, sort its values, get indexOf, and null the value in the sorted copy:

const sortIndicesByValue = array => {
  const sorted = [...array].sort((a, b) => a - b);
  return array.map(e => {
    const i = sorted.indexOf(e);
    sorted[i] = null;
    return i;
  })
}

console.log(...sortIndicesByValue([32, -3, 62, 8, 121, -231, 62, 13]));
console.log(...sortIndicesByValue([-1, 3, 0, 0, 2, 9, -2, 7]));
Kosh
  • 16,966
  • 2
  • 19
  • 34