-4

I have multiple arrays in a main/parent array like this:

var arr = [
    [1, 17],
    [1, 17],
    [1, 17],
    [2, 12],
    [5, 9],
    [2, 12],
    [6, 2],
    [2, 12],
    [2, 12]
];

I have the code to select the arrays that are repeated 3 or more times (> 3) and assign it to a variable.

The code is:

var arr = [[1, 17], [1, 17], [1, 17], [2, 12], [5, 9], [2, 12], [6, 2], [2, 12]]
arr.sort((a, b) => a[0] - b[0] || a[1] - b[1])

// define equal for array
const equal = (arr1, arr2) => arr1.every((n, j) => n === arr2[j])

let GROUP_SIZE = 3
first = 0, last = 1, res = []

while(last < arr.length){
    if (equal(arr[first], arr[last])) last++
    else {
        if (last - first >= GROUP_SIZE)  res.push(arr[first])
        first = last
    }
}
if (last - first >= GROUP_SIZE)  res.push(arr[first])
console.log(res)

So the final result is:

console.log(repeatedArrays);
>>> [[1, 17], [2, 12]]

My problem: But the problem is, I have an array like this {from: [12, 0], to: [14, 30]}.

var arr = [
    [1, 17],
    [1, 17],
    [1, 17],
    [2, 12],
    [5, 9],
    [2, 12],
    [6, 2],
    {from: [12, 0], to: [14, 5]},
    {from: [12, 0], to: [14, 5]},
    {from: [4, 30], to: [8, 20]},
    {from: [12, 0], to: [14, 5]},
    {from: [4, 30], to: [8, 20]},
    [2, 12],
    [2, 12]
];

When I try to use the above code, it doesn't work. The error message is:

Uncaught TypeError: arr1.every is not a function

The final result should be:

console.log(repeatedArrays);
>>> [[1, 17], [2, 12], {from: [12, 0], to: [14, 5]}]

How can I make that code above work?

Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
baileyJchoi
  • 473
  • 5
  • 17
  • 7
    What sort of logic are you looking for? Would you need to find 3 duplicates of the full `{ from, to }` object for it to be included in the final result, or what? – CertainPerformance Apr 18 '19 at 02:05
  • https://stackoverflow.com/questions/36784726/find-duplicate-array-within-array – Santosh Apr 18 '19 at 02:09
  • You need to pass in an array. `{from: [12, 0], to: [14, 5]}` is an object. – josephting Apr 18 '19 at 02:18
  • *"...I have an array like this `{from: [12, 0], to: [14, 30]}`"* How is that object equivalent to: `var array = [ [1, 17], [1, 17], [1, 17], [2, 12], [5, 9], [2, 12], [6, 2], {from: [12, 0], to: [14, 5]}, [2, 12], [2, 12] ];` ? And why is this object: `{from: [12, 0], to: [14, 5]}` stuffed in an array of arrays so haphazardly? – zer00ne Apr 18 '19 at 02:35

3 Answers3

1

If you introduce a non array into the mix, you need to handle it differently.

Yours already work with array so I'm adding object style check for both sort and equal.

var arr = [
  [1, 17],
  [1, 17],
  [1, 17],
  [2, 12],
  [5, 9],
  [2, 12],
  [6, 2],
  { from: [4, 30], to: [8, 21] },
  { from: [12, 0], to: [14, 5] },
  { from: [12, 0], to: [14, 5] },
  { from: [4, 30], to: [8, 20] },
  { from: [12, 0], to: [14, 5] },
  { from: [4, 30], to: [8, 20] },
  [2, 12],
  [2, 12]
];
arr.sort((a, b) => {
  if (a instanceof Array && b instanceof Array) {
    return a[0] - b[0] || a[1] - b[1]
  } else if (a instanceof Array || b instanceof Array) {
    return a instanceof Array ? -1 : 1
  } else {
    return a.from[0] - b.from[0] || a.from[1] - b.from[1] || a.to[0] - b.to[0] || a.to[1] - b.to[1]
  }
});

// define equal for array
const equal = (arr1, arr2) => {
  if (arr1 instanceof Array) {
    return arr1.every((n, j) => n === arr2[j]);
  } else {
    if (arr2 instanceof Array) return false;
    for (let k in arr1) {
      if (!arr1[k].every((n, j) => n === arr2[k][j])) {
        return false
      }
    }
    return true;
  }
};

let GROUP_SIZE = 3;
(first = 0), (last = 1), (res = []);

while (last < arr.length) {
  if (equal(arr[first], arr[last])) last++;
  else {
    if (last - first >= GROUP_SIZE) res.push(arr[first]);
    first = last;
  }
}
if (last - first >= GROUP_SIZE) res.push(arr[first]);
console.log(res);
josephting
  • 2,617
  • 2
  • 30
  • 36
0

You can use the function reduce for grouping and counting the objects and then execute the function filter for getting the object with count >= 3.

var array = [     [1, 17],     [1, 17],     [1, 17],     [2, 12],     [5, 9],     [2, 12],     [6, 2],     [2, 12],     [2, 12] ];

let result = Object.values(array.reduce((a, [c, b]) => {
  let key = `${c}|${b}`;
  (a[key] || (a[key] = {count: 0, value: [c, b]})).count++;
  return a;
}, {})).filter(o => {
  if (o.count >= 3) {
    delete o.count;
    return true;
  }
  
  return false;
}).map(({value}) => value);

console.log(result);
.as-console-wrapper { min-height: 100%; }
Ele
  • 33,468
  • 7
  • 37
  • 75
0

Really simple - filter it all, then remove duplicates with Set and JSON methods (because it's nested arrays not objects):

var array = [
    [1, 17],
    [1, 17],
    [1, 17],
    [2, 12],
    [5, 9],
    [2, 12],
    [6, 2],
    [2, 12],
    [2, 12]
];

var repeatedArrays = [...new Set(array.filter(e => array.filter(f => JSON.stringify(e.sort()) == JSON.stringify(f.sort()))).map(JSON.stringify))].map(JSON.parse);

console.log(repeatedArrays);
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79