skip to Main Content

I have an array like this : [‘a’, ‘a’, ‘b’, ‘c’, ‘a’ ]

I want to obtain this : [0, 0, 1, 2, 0]

The idea is to give the first value of the arr1 array 0 value, the second 1, etc…

I tried this :

function onlyUnique(value, index, array) {
  return array.indexOf(value) === index;
}
let arr1 = ['a', 'a', 'b', 'c', 'a' ]
var arr1_uniq= arr1.filter(onlyUnique);
let k=0
var list = []
for (let i in arr1_uniq){
    list.push(k)
    k++
}

So I have the arr1 without duplicate : [‘a’, ‘b’, ‘c’] And the corresponding values : [0, 1, 2]

And finally I tried to use the findIndex function to reallocate arr1 values but I have issues.

3

Answers


  1. It should be possible by mapping the values to its unique index like this:

    function indexMapper(arr) {
        const uniqueValues = [...new Set(arr)];
        const inverseMap = Object.fromEntries(uniqueValues.map((val, index) => [val, index]));
        return arr.map(value => inverseMap[value]);
    }
    
    // Example usage
    let arr1 = ['a', 'a', 'b', 'c', 'a'];
    let result = indexMapper(arr1);
    console.log(result);  // [0, 0, 1, 2, 0]
    Login or Signup to reply.
  2. You can use a Map<Object, Number> and a counter to keep track of the indices.

    const indexArray = (arr) => {
      const lookup = new Map();
      let currIndex = 0;
      return arr.map((item) => {
        if (lookup.has(item)) return lookup.get(item);
        lookup.set(item, currIndex);
        return currIndex++;
      });
    };
    
    const arr = ['a', 'a', 'b', 'c', 'a'];
    const res = indexArray(arr);
    
    console.log(...res); // [0, 0, 1, 2, 0]

    You can remove the need for the currIndex if you utilize the size property of the map.

    const indexArray = (arr) => {
      const lookup = new Map();
      return arr.map((item) => {
        if (!lookup.has(item)) {
          lookup.set(item, lookup.size);
        }
        return lookup.get(item);
      });
    };
    
    const arr = ['a', 'a', 'b', 'c', 'a'];
    const res = indexArray(arr);
    
    console.log(...res); // [0, 0, 1, 2, 0]

    Here it is in one line:

    const indexArray = (arr) =>
      (lookup =>
        arr.map((item) =>
          (lookup.has(item)
            ? lookup
            : lookup.set(item, lookup.size)
          ).get(item)))
      (new Map());
    
    const arr = ['a', 'a', 'b', 'c', 'a'];
    const res = indexArray(arr);
    
    console.log(...res); // [0, 0, 1, 2, 0]

    And now, the code golf:

    // 64 bytes
    f=a=>(m=>a.map(e=>(m.has(e)?m:m.set(e,m.size)).get(e)))(new Map)
    
    console.log(...f(['a', 'a', 'b', 'c', 'a'])) // [0, 0, 1, 2, 0]
    Login or Signup to reply.
  3. Here is the desired code sample using Map:

    function mapToIndexes(arr) {
        const map = new Map();
        return arr.map((item, index) => {
            if (!map.has(item)) {
                map.set(item, map.size);
            }
            return map.get(item);
        });
    }
    
    const arr = ['a', 'a', 'b', 'c', 'a'];
    const result = mapToIndexes(arr);
    console.log(result); // Output: [0, 0, 1, 2, 0]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search