1

Given

arr = [1,5,3,5,1,5,6,6,6];

If I wanted to find the elements that appear, say x = 3 times in the array, how would I do so without the use of objects? i.e. 5,6. Via array methods preferably.

blex
  • 24,941
  • 5
  • 39
  • 72
kite
  • 309
  • 2
  • 12
  • Arrays are objects too! Also, you can abuse arrays or functions to set key-value properties on them or use the `Map` data structure, depending on how you can bend the requirements (not that it's necessary to do so, it just makes O(n) harder to achieve which is the optimal time complexity for this). Lastly, you should show an attempt at solving this yourself. – ggorlen Jul 05 '20 at 00:15
  • I'm not showing an attempt unless it's relevant to solving/explaining the problem. Nor am I going to explain I know how to solve it via other ways. Nor that this is a simplified outline I cameup with that was to help me solve a part of a problem I'm struggling 2+hr on. I can go on, you get the point. Post a link if you feel I didn't google properly, so I can improve my searching going forward. Arrays are objects too...great. How should I have clearly and concisely indicated I knew the object solution and wanted an array method solution? Suggest an edit, that would be a useful contribution. – kite Jul 05 '20 at 01:36

3 Answers3

3

You should be able to achieve that using only filter(), indexOf(), and reduce():

function filterByCount(array, count) {
  return array.filter((a, index) =>
    array.indexOf(a) === index &&
    array.reduce((acc, b) => +(a === b) + acc, 0) === count
  );
}

const arr = [1, 5, 3, 5, 1, 5, 6, 6, 6];

console.log(filterByCount(arr, 3));

Note that this approach is fairly inefficient. With the use of classes like Map, you could achieve this in O(n) time instead of O(n2) time.


Another less simple approach that achieves this in O(n log(n)) time is to sort the array then compare the difference between the first and last index of each value with the expected count. This solution requires sort() and filter(). If you don't want to mutate the original array, then slice() is required as well:

function filterByCount(array, count) {
  // uncomment to avoid mutating the input array
  return array/*.slice()*/.sort((a, b) =>
    a - b
  ).filter((value, index, sorted) =>
    (index === 0 || sorted[index - 1] !== value) &&
    index + count - 1 < sorted.length &&
    sorted[index + count - 1] === value &&
    (index + count >= sorted.length || sorted[index + count] !== value)
  );
}

const arr = [1, 5, 3, 5, 1, 5, 6, 6, 6];

console.log(filterByCount(arr, 3));
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
2

Just an idea, though, if you can sort the array, you can count the numbers that appear consecutively.

function findRepeatingNumbers(numbers, count) {
  numbers.sort((a, b) => a - b);

  const found = [];
  let counter = 1;

  for (let i = 1; i < numbers.length; i++) {
    if (numbers[i - 1] == numbers[i]) {
      counter += 1;
    } else {
      if (counter === count) {
        found.push(numbers[i - 1]);
      }
      counter = 1;
    }
  }

  if (counter == count) {
    found.push(numbers[numbers.length - 1]);
  }

  return found;
}

console.log(findRepeatingNumbers([1, 5, 3, 5, 1, 5, 6, 6, 6], 3));
shotasenga
  • 939
  • 7
  • 17
1

If you want to find the elements that appear, how many times in the array, you can easily know this following code. For example, here 6 is 3 times in this array.

Run the snippet check it out.

let arr = [1, 5, 3, 5, 1, 5, 6, 6, 6];
console.log((arr.join("").match(new RegExp("6", "g")) || []).length)
Talha Noyon
  • 824
  • 7
  • 13