4

I have an array to be like this
var arr = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5].

so it contains duplicate values. In here last index value of
'0' is '3',
'1' is '4',
'2' is '5',
'3' is '13',
and so on.
And i counted total duplicate values

var counts = {};
arr.forEach(function(x) { counts[x] = (counts[x] || 0)+1; })


but i want to know last duplicate value index only. please help me.
thanks in advance

10
  • And how do you want the results? Commented Feb 2, 2016 at 19:07
  • i want the result in an array. Commented Feb 2, 2016 at 19:08
  • Seeing as counts is an object, there is no "last", as there is no order Commented Feb 2, 2016 at 19:10
  • Will the array always be sorted? Commented Feb 2, 2016 at 19:10
  • 1
    Will the array always have values grouped together (ie. [0,0,1,1,2,2]) or can they be scattered (ie. [0,1,2,0,1,2])? Commented Feb 2, 2016 at 19:16

4 Answers 4

7
var arr = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5];
var existingItems = {};

arr.forEach(function(value, index) {
    existingItems[value] = index;
});

console.log(existingItems);
Sign up to request clarification or add additional context in comments.

3 Comments

@adeneo, nope. It uses the second parameter of forEach, which is the index, instead of the first one, which is the value. It also overwrites each previous index with the new index, thus at the end it will contain the last index. +1 @Shaun, we think alike :)
@nem - I finally got the point, it just seemed so strange I got confused
I like this solution. Also works for unsorted arrays! +1
1

Simple loop and check to see if next index is different

var arr = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5]
var indexes = arr.reduce(function(result, cur, ind, arr){
   if (ind+1===arr.length || cur != arr[ind+1]) {  //check to see if last or different
       result.push(ind);  //if different, store the index
   }
   return result;
},[]);
console.log(indexes);

1 Comment

This is probably the only correct answer, since OP said he wants an array. Specially since he doesn't specify anything about how the array should look.
0

Array.prototype.lastIndexOf() comes in handy here:

var arr = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5];

var out = {};

arr.forEach(function(item) {
  if(!out.hasOwnProperty(item)) {
    out[item] = arr.lastIndexOf(item);
  }
});

console.log(out); // Object {0: 3, 1: 4, 2: 5, 3: 13, 4: 15, 5: 22}

This will also work for unsorted input arrays.

4 Comments

This might be an overkill considering that lastIndexOf performs a loop over the array for each element, thus O(N^2), while this can be done in O(N).
@nem I agree. However, depending on the situation, the more readable and maintainable code may be worth the (minor) performance penalty. Also, this way we do not rely on the premise that the array is sorted.
Going from O(N) to O(N^2) is certainly not a minor performance penalty. Also, you already have the index passed into forEach, so yo can just use it instead of calling lastIndexOf, hence readability as well ^_^.
I just saw Shaun's solution and I like it better than mine. Note though that lastIndexOf will only be called once per unique item, not once per element of arr, which makes it a little less bad... :-)
0

Well, what you can do is check if a value is a duplicate (count > 1) and then use the second parameter of forEach which is the index to remember it. Something like:

var arr = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5];
var counts = {};
var indexes = {};
arr.forEach(function(x, idx) {
  counts[x] = (counts[x] || 0) + 1;
  if(counts[x] > 1) { indexes[x] = idx; } // check if a value is a duplicate and update its index
});

// logs the last index of all duplicate values
console.log(indexes); // {0: 3, 3: 13, 4: 15, 5: 22}

If you want the last index of all values, not just duplicates, you can omit the count > 1 check:

var arr = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5];
var counts = {};
var indexes = {};
arr.forEach(function(x, idx) {
  counts[x] = (counts[x] || 0) + 1;
  indexes[x] = idx; // update value index
});

// logs the last index of all values
console.log(indexes); // {0: 3, 1: 4, 2: 5, 3: 13, 4: 15, 5: 22}

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.