Evan DiGi Evan DiGi - 5 months ago 8
Javascript Question

Returning duplicates in multidimensional Javascript array

I have searched high and low, not only on StackOverflow, but many other places elsewhere on the web. I've tried what seems like everything, but something is fundamentally flawed with my logic. I apologize for introducing another "Duplicates in Array" question, but I am stuck and nothing seems to be working as expected.

Anyway, I have a multi-dimensional JavaScript array, only 2 levels deep.

var array = [[Part #, Description, Qty:],
[Part #, Description, Qty:],
[Part #, Description, Qty:]]; //etc


What I need to do is create a function that searches
array
and returns any duplicate "Part #" lines. When they are returned, I would like to have the entire inner array returned, complete with description and qty.

The trick with this is that the Part #'s that would qualify as 'duplicate' would end differently (specifically the last 4 characters), so using
String.prototype.substr
makes sense (to me).

I know there are duplicates in the array in the way that I am looking for, so I know that if I had the solution, it would return those Part #'s.

Here is what I have tried so far that gets me the closest to a solution:

function findDuplicateResults(arr) {
var result = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i][0].substr(0,5) === arr[++i][0].substr(0,5)) {
result.push(arr[i]);
}
}
return console.log(result);


}

My thinking is that if the element in the array(with substr(0,5) is equal to the next one in line, push that to the result array. I would need the other duplicate in there too. The point of the code is to show only dupes with substr(0,5).

I have tried using Higher Order Functions such as map, forEach, reduce, and filter (filter being the one that boggles my mind as to why it doesn't do what I want), but I have only been able to return
[]
or the entire array that way. The logic that I use for said Higher Order Functions remains the same (which is probably the problem here).

I am expecting that my
if
condition is where the most of the problem is. Any pointers or solutions are greatly appreciated.

Answer

There is a mistake in your code. When you use ++i, you are changing the value of i, so it is going to skip one item in the next iteration.

Regarding the logic, you are only comparing one item to the next item, when you should really be comparing each item to all items:

function findDuplicateResults(arr) {
  var result = [];
  for (var i = 0; i <= arr.length - 1; i++) {
    for (var k = 0; k <= arr.length - 1; k++) {
      if (i !== k && arr[i][0].substr(0,5) === arr[k][0].substr(0,5)) {
        result.push(arr[i]); 
      }
    }
  }
  return result;
}

Although, the 'substr' could be dropped, and 'for' loop could be replaced by a higher order function:

function findDuplicateResults(arr) {
  return arr.filter(function(item1){
    return arr.filter(function(item2){
      return item1[0] === item2[0];
    }).length > 1;
  });
}