小能豆

Get all unique values in a JavaScript array (remove duplicates)

javascript

I have an array of numbers that I need to make sure are unique. I found the code snippet below on the internet and it works great until the array has a zero in it. I found this other script here on Stack Overflow that looks almost exactly like it, but it doesn’t fail.

So for the sake of helping me learn, can someone help me determine where the prototype script is going wrong?

Array.prototype.getUnique = function() {
 var o = {}, a = [], i, e;
 for (i = 0; e = this[i]; i++) {o[e] = 1};
 for (e in o) {a.push (e)};
 return a;
}

阅读 241

收藏
2023-12-29

共1个答案

小能豆

The issue with the provided script is that it uses an object (o) to keep track of unique values. When the array contains numbers, the numbers are converted to strings when used as object keys. This can lead to unexpected behavior, especially when dealing with the number 0.

Let’s break down the script:

Array.prototype.getUnique = function() {
    var o = {}, a = [], i, e;
    for (i = 0; e = this[i]; i++) {
        o[e] = 1;
    }
    for (e in o) {
        a.push(e);
    }
    return a;
};

Here, o is an object used to keep track of unique values, and a is the resulting array of unique values. The loop for (i = 0; e = this[i]; i++) iterates over the elements of the array and sets o[e] to 1, effectively using the array elements as keys in the object.

However, when numbers are used as keys, they are implicitly converted to strings. This causes an issue when the array contains the number 0 because o[0] and o["0"] are treated as the same key. As a result, the script fails to distinguish between 0 and "0".

Here’s an improved version of the script that handles numbers correctly:

Array.prototype.getUnique = function() {
    var o = {}, a = [], i, e;
    for (i = 0; i < this.length; i++) {
        e = this[i];
        // Use a string representation to handle numbers correctly
        var key = typeof e === 'number' ? e.toString() : e;
        o[key] = 1;
    }
    for (e in o) {
        // Convert the keys back to their original type if possible
        a.push(isNaN(Number(e)) ? e : Number(e));
    }
    return a;
};

This version uses a string representation for keys and converts them back to their original type when creating the result array. This ensures that numbers, including 0, are handled correctly.

2023-12-29