1
function firstDuplicate(a) {
  var numbers = {},
      res;

foo:
  for (var i = 0; i < a.length; i++) {
    for (var j = i + 1; j < a.length; j++) {
      if (a[i] === a[j]) {
        numbers[a[i]] = j - i;
        if (j - i === 1 ) {
            break foo;
        }
      }
    }
  }

  var keys = Object.keys(numbers),
      res = keys[0];

  keys.forEach(function (v) {
    res = numbers[res] > numbers[v] ? v : res;
  });

  console.log(res);

  return res === undefined ? -1 : Number(res);
}

This function returns the first duplicate value in the array of numbers.

I want to decrease its execution time. What changes should I do?

Examples

  1. For a = [2, 3, 3, 1, 5, 2], the output should be firstDuplicate(a) = 3.

There are 2 duplicates: numbers 2 and 3. The second occurrence of 3 has a smaller index than the second occurrence of 2 does, so the answer is 3.

  1. For a = [2, 4, 3, 5, 1], the output should be firstDuplicate(a) = -1.
6
  • This functions definitely doesn't return "the first duplicate in the array". What do you really want to do? Commented Dec 24, 2017 at 12:27
  • @JakubDąbek I think he wants to return index of the first duplicate Commented Dec 24, 2017 at 12:30
  • I think OP wants an index where the next duplicate comes as soon as possible. But I think it fails, because numbers[a[i]] gets overridden so that it only looks at the last pair of duplicates for each value of a[i]. So if a = ['a', 'a', 'b', 'a'], then it will find the (1,3) pair instead of the (0,1) pair. But yes, this definitely needs more clarity. Commented Dec 24, 2017 at 12:39
  • 1
    @GaneshSundaram you want "the first duplicate value in the array of numbers". So if a = [4, 4, 9, 9] you want to return 4. What if a = [4, 9, 9, 4]? Commented Dec 24, 2017 at 12:44
  • Why do you convert your value to a number if you don't look for an index? Commented Dec 24, 2017 at 12:47

3 Answers 3

3

If the array contains number or string you can do something like this,

//Returns the first duplicate element   
function firstDup(arr) {
  let o = {}; //an empty object
  for (let i = 0; i < arr.length; i++) {
    if (o[arr[i]]) { //check if the property exists
      return arr[i];
    } else {
      o[arr[i]] = 'a'; //set the object's property to something non falsy
    }
  }
  return -1; //If No duplicate found return -1
}

console.log(firstDup([2, 3, 3, 1, 5, 2]));
console.log(firstDup([2, 4, 3, 5, 1]));

Sign up to request clarification or add additional context in comments.

Comments

2

function firstDuplicate(array) {
  const numbers = {};
  
  for (const number of array) {
    if (numbers[number]) {
      return number;
    } else {
      numbers[number] = true;
    }
  }
  
  return -1; // No duplicate
}

const duplicate = firstDuplicate([1, 2, 3, 4, 5, 6, 10, 1, 3]);
console.log(duplicate)

Comments

1

You may instead use find and indexOf :

 function findFirstDupe(array) {
   return array.find((n, i) => array.indexOf(n) !== i);
 }

Or you use a Set to check for previous appearances:

function findFirstDupe(array){
  const set = new Set();
  return array.find(n => set.has(n) || (set.add(n), false));
}

The same with an object as a hash:

function findFirstDupe(array){
  const hash = {};
  return array.find(n => !(hash[n] = !hash[n]))
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.