8

Possible Duplicate:
Easiest way to find duplicate values in a JavaScript array

I am looking to find if two values are the same in an Array. I have written the following code:

function validatePassTimeFields(passtimes) {
    var success = true; 
    var length = passtimes.length;
    var hashMap = new Object();
    for (var j=0; j<length; j++) {
        if(hashMap[passtimes[j].value]==1) {
            success = false;
            alert("Duplicate Found");
            break;
        }
        hashMap[passtimes[j].value]=1;
    }
    return success;
}

I am new to Javascript, so I tried using HashMap like to find if there is any duplicate. IS it the best way of finding a duplicate in JavaScript? or I can optimize it?

Community
  • 1
  • 1
sheidaei
  • 9,842
  • 20
  • 63
  • 86
  • do you want to "find" duplicates or "eliminate" them? –  Oct 04 '12 at 17:21
  • 1
    See if any of these solutions help: http://stackoverflow.com/questions/840781/easiest-way-to-find-duplicate-values-in-a-javascript-array – Chase Oct 04 '12 at 17:21
  • @JarrodRoberson I just want to find them. And if there is only one of them is enough for me. – sheidaei Oct 04 '12 at 17:22
  • @Chase thanks, but sorting and then finding is not a better way, is it? – sheidaei Oct 04 '12 at 17:23
  • 4
    This is a surprisingly good function for someone who's new to JS. +1 – NullUserException Oct 04 '12 at 17:24
  • 1
    @NullUserException tnx, what do you mean it doesn't really work? are you talking about the code I've written? I tested it and it works. – sheidaei Oct 04 '12 at 17:27
  • @sheidaei, check the solution that has the most up votes and not the accepted answer as it seems to be the better way to handle duplicates. Either way, your code seems fine to me. – Chase Oct 04 '12 at 17:30
  • 2
    Your code should work fine, but this question should probably be on http://codereview.stackexchange.com instead of this site. – I Hate Lazy Oct 04 '12 at 17:30
  • I don't quite understand what is the purpose of your code. hashMap'll be filled with 1 and there will be no alert – Den T Oct 04 '12 at 17:31
  • 2
    @sheidaei: Your functions considers values as equal (duplicate) if they cast to the same string (i.e. it works for an array of strings, but not for arrays of objects etc) – Bergi Oct 04 '12 at 17:32
  • @sheidaei I'm getting false positives here because `.value` always gives me `undefined`: http://jsfiddle.net/apVVE/ – NullUserException Oct 04 '12 at 17:35
  • @DenTarbaev: It'll be filled with `1`, and the loop will continue. If another item with the same `.value` is found, it will be located in the `hashMap` so the `==` test will pass you'll get the alert. – I Hate Lazy Oct 04 '12 at 17:36
  • 1
    There's no significantly better way to do this check. It's up to you, of course, but it's quite common in JS to return false from inside that loop instead of storing the result in a local variable. That would clean up the code a bit. – Scott Sauyet Oct 04 '12 at 17:37
  • @user1689607 tnx, so many sites :D can someone move it there? – sheidaei Oct 04 '12 at 17:37
  • @Bergi tnx, +1 I didn't think about that – sheidaei Oct 04 '12 at 17:38
  • A mod like @NullUserException should be able to move it. – I Hate Lazy Oct 04 '12 at 17:38
  • @NullUserException I guess you are right, I have to take care about that, tnx again – sheidaei Oct 04 '12 at 17:39
  • @NullUserException: Don't you think that perhaps it should be an Array of objects that have a `.value` property? Doesn't seem like this is meant to be a general purpose function. – I Hate Lazy Oct 04 '12 at 17:43
  • @user1689607 I suppose that's true; you're right. – NullUserException Oct 04 '12 at 17:46

4 Answers4

1

// You would only need to optimize it if you want to use it elsewhere-

function noduplicates(array){
    var next, O= {},
    L= array.length;
    while(L){
        next= array[--L];
        if(O[next]) return false;
        O[next]= 1;
    }
    return true;
}


function validatePassTimeFields(passtimes){
    if (noduplicates(passtimes)) return true;

    alert("Duplicate Found");
    return false;
}
kennebec
  • 102,654
  • 32
  • 106
  • 127
  • I am testing your code http://jsfiddle.net/GubnU/ and it works fine. However, when I am running it locally I have to change the line where you assign the next value to the following: next= array[--L].value; Any idea why? – sheidaei Oct 04 '12 at 18:25
1

Your function is already very good, apart from the issue that it only works for arrays with strings or numbers. For a more difficile approach to care also about objects see this answer. I don't think that matters for you as you have an explicit and restricted use case (checking identity by the value property).

However, some points I'd do different:

  • Don't use the success variable and break from the loop, but just return from the whole function.
  • Instead of the constructor new Object usually the shortcut object literal {} is used
  • Instead of setting the values in the hashMap to 1 one might use true; you also could omit the equality operator == and just check for the truthiness of the property. I even would use the in operator.
function validatePassTimeFields(passtimes) {
    var length = passtimes.length;
    var hashMap = {};
    for (var j=0; j<length; j++) {
        if (passtimes[j].value in hashMap) {
            alert("Duplicate Found");
            return false;
        }
        hashMap[passtimes[j].value] = 1;
    }
    return true;
}
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

It seems that you do not want to find the duplicates, only to see if there are any?

You're pretty close, here's a working function;

var hasDuplicates = function (arr) {

    var _store = {};

    for (var i = 0; i < arr.length; i++) {

        if (typeof _store["_" + arr[i]] !== "undefined") {
            return true;
        }

        _store["_" + arr[i]] = true;

    }

    return false;

};

The underscores in the associative array are necessary for storing numeric values. The hasDuplicates() function only works objects which have a toString() method.

To check for duplicates;

var yourArray  = [1, 5, 7, 3, 5, 6];

if (hasDuplicates(yourArray)) {...
Björn
  • 29,019
  • 9
  • 65
  • 81
0

It might be worth checking out underscore's implementation of this functionality. If you are just looking to eliminate dupes, you can use _.uniq(), but if you are more interested in just knowing that there are dupes or the pure implementation details, you might enjoy checking out the source of this method, which is very nicely documented.

I know this isn't a direct code answer to the question - there are a few here already so it wouldn't be useful to repeat. But I thought it was worth mentioning as underscore is a great utility library and the source is a great place to learn more about well-written javascript.

Jeff Escalante
  • 3,137
  • 1
  • 21
  • 30