0

I am trying to get the indices of duplicates in an array., but can't get my code working for some reason.

I've tried the following

var arr = [
        ["OPEL", "12365", "TY"],
        ["FORD", "52874", "QW"],
        ["OPEL", "96542", "TY"],
        ["FIAT", "45621", "TY"], 
        ["FIAT", "74125", "QW"],
        ["FORD", "52874", "QW"]
];

function FindDuplicates(){
    var a = arr.sort();
    for (var i = 0; i < a.length-1; i++){
        if (a[i+1] == a[i]){
        alert(i);
        }
    }
}

Can anyone tell what I am doing wrong here?

Ethannn
  • 191
  • 1
  • 2
  • 16
  • You should tag the language – Zarwan Aug 31 '15 at 16:09
  • You have to edit your post and add it to where you added the duplicate tag. – Zarwan Aug 31 '15 at 16:10
  • I see, sorry for that – Ethannn Aug 31 '15 at 16:11
  • 1
    I don't use JavaScript, but usually when indexing a multidimensional array you need multiple indices. In your case `arr[index of sublist][index of element in sublist]` – Zarwan Aug 31 '15 at 16:13
  • 1
    What are the criteria to compare one element with the other ? Right now you are using the element memory address. – MaxZoom Aug 31 '15 at 16:14
  • @Zar thanks that solved the problem! – Ethannn Aug 31 '15 at 16:18
  • No problem, I'll post it as an answer. – Zarwan Aug 31 '15 at 16:18
  • As @MaxZoom has stated, your example does not include any duplicates and your first dimension of the array is pointing to a memory address that holds a reference to another array. Your second dimension would be a value of that array, but what is your definition of a duplicate? Is it the Make? The Zipcode? Whatever that third field is? A combination of the three? – vol7ron Aug 31 '15 at 16:25
  • @vol7ron I edited my post. A duplicate is something like this `["FORD", "52874", "QW"]` – Ethannn Aug 31 '15 at 16:33

4 Answers4

0

When indexing a multidimensional array you need multiple indices. In your case arr[index of sub-array][index of element in sub-array].

Zarwan
  • 5,537
  • 4
  • 30
  • 48
  • still one thing. It returns only the index of 1 of the 2 indices of the duplicates – Ethannn Aug 31 '15 at 16:22
  • @Ethannn this answer should probably be upvoted, but not selected as an answer – vol7ron Aug 31 '15 at 16:26
  • @Ethannn you can modify your function to return both indices: http://stackoverflow.com/questions/2917175/return-multiple-values-in-javascript – Zarwan Aug 31 '15 at 16:46
0

A few things to point out:

  • a should not be used as a variable name; while it may work, programming convention is to use that variable name for sorting (in some languages, using it in open code this could cause problems)

  • a and arr are pointing to the same array in memory; since you are not copying all the elements (and subelements) of arr into a, they will both be referencing the same value, so a is useless and the sort will be applied to arr

  • as @Saar has pointed out, since all your elements determine the uniqueness of your array, you can cast the array as a string and compare that value to the string of the next array

See:

console.clear();
var arr = [
        ["OPEL", "12365", "TY"],
        ["FORD", "52874", "QW"],
        ["OPEL", "96542", "TY"],
        ["FIAT", "45621", "TY"], 
        ["FIAT", "74125", "QW"],
        ["FORD", "52874", "QW"]
];

function sortAlphabetically(a,b){
  var a_lower = a.toString().toLowerCase(),
      b_lower = b.toString().toLowerCase();

  // sort ascending (a comes first)
  if (a_lower < b_lower)
    return -1;

  // b comes first (move a behind b)
  if (a_lower > b_lower)
    return 1;

  // default: a and b are the same (no sort)
  return 0;
}


function FindDuplicates(){
  arr.sort(sortAlphabetically);

  for (var i = 0; i < arr.length-1; i++){
    if (arr[i+1]+'' == arr[i]+''){
      console.log('Duplicate at: ', 
                  [
                    '[', i, ']',
                    ' and ',
                    '[', i+1, ']',
                    '\n\tvalue: "',arr[i],'"'
                  ].join(''));
    }
  }
}

FindDuplicates();
vol7ron
  • 40,809
  • 21
  • 119
  • 172
0

You can create a Hash object that will store already visited elements. If the new coming element has the same key as previously used then it is a duplicate.

var arr = [
  ["OPEL", "12365", "TY"],
  ["FORD", "52874", "QW"],
  ["OPEL", "96542", "TY"],
  ["FIAT", "45621", "TY"],
  ["FIAT", "74125", "QW"],
  ["FORD", "52874", "QW"]
];

var findDups = function(a) {
  var hash = {};
  for (var i = 0; i < a.length; i++) {
    var key = a[i].toString();
    if ( hash[key] ) {
      alert("Found duplicate at index " + i + " for " + key);
    }
    else {
      hash[key] = true;
    }
  }
}(arr);
MaxZoom
  • 7,619
  • 5
  • 28
  • 44
-1

You basically have an array inside of another array, when trying to compare arrays == will not work for you.

In your case since the array is all strings you can do:

a[i+1].toString() === a[i].toString()

This would work specifically for your case, if you want a more robust code check the answers in this thread on how to check array equality: How to check if two arrays are equal with JavaScript?

Community
  • 1
  • 1
Saar
  • 2,276
  • 1
  • 16
  • 14
  • The solution provided by @Zar seesm to work though. Only thing is that it only returns the 1st matched index – Ethannn Aug 31 '15 at 16:34
  • Another thing. My code creates a new array called `a` and sorts the data from array `arr` in it. But for some reason `arr` ends up sorted as well ??? – Ethannn Aug 31 '15 at 16:41
  • @Ethannn you are not creating a new array, you are a creating a new variable that references the same array. You must perform a deep copy if that's what you want to do. `a` and `arr` are pointing to the same array in memory. Also, you should not use `a` as a variable name as convention is to use that for sorting variables. – vol7ron Aug 31 '15 at 16:47
  • But if I am creating a new variable, shouldn't the previous variable remain unchanged? – Ethannn Aug 31 '15 at 17:12
  • Why are you voting down if it's working? I didn't say it was a best practice.. I pointed him to correct location. – Saar Aug 31 '15 at 21:17