Какой вариант поиска уникального элемента в массиве лучше по производительности в целом?

Решав задачу меня занял вопрос: какой вариант поиска уникального элемента в целочисленном массиве размером больше 2 элементов (один нечетный или один четный) будет лучше по производительности:

  1. Два вызова filter:
function findOutlier(arr){
  var even = arr.filter(a=>a%2==0);
  var odd = arr.filter(a=>a%2!==0);
  return even.length==1? even[0] : odd[0];
}
  1. Проход forEach и push
function findOutlier(arr){
  let ev = [],
      od = [];
  arr.forEach(e => (e & 1) ? ev.push(e) : od.push(e) );
  return ev.length > 1 ? od[0] : ev[0];
}

Ответы (2 шт):

Автор решения: Leonid

Как минимум можно по первым трем элементам определить какой элемент искать в качестве уникального. Складываю остаток от деления первых трех чисел, и , если он больше 2, то надо искать первое же четное и возвращать его. И наоборот.

Конечно в некоторых случаях можно и двумя первыми элементами обойтись, но это усложнение условия.

function findOutlier(arr){ // Минимальная длина массива - 3!
    return arr.slice(0,3).reduce((sum,item) => sum + item%2, 0) >= 2 ? arr.find(i => i%2==0) : arr.find(i => i%2!=0);
}

console.log(findOutlier([3,4,5,7,9,11]));
console.log(findOutlier([3,1,11,17,19,21,3,1,2,29]));
console.log(findOutlier([4,8,2,1,80,20]));
console.log(findOutlier([4,3,3]));

Или обойтись простым выражением вместо slice + reduce:

function findOutlier(arr){ // Минимальная длина массива - 3!
    return arr[0]%2 + arr[1]%2 + arr[2]%2 >= 2 ? arr.find(i => i%2==0) : arr.find(i => i%2!=0);
}

console.log(findOutlier([3,4,5,7,9,11]));
console.log(findOutlier([3,1,11,17,19,21,3,1,2,29]));
console.log(findOutlier([4,8,2,1,80,20]));
console.log(findOutlier([4,3,3]));

→ Ссылка
Автор решения: Alexey Ten
function findOutlier(arr) {
  // Если первые два элемента разной чётности
  if ((arr[0] + arr[1]) % 2) {
    // то сравним чётность с третьим элементом
    return (arr[0] + arr[2]) % 2 ? arr[0] : arr[1];
  } else {
    const a = arr[0];
    // первые два элемента одной чётности, ищем элемент другой
    // чётности начиная с третьего
    for (let i = 2; i < arr.length; i++) {
      if ((a + arr[i]) % 2) return arr[i];
    }
  }
}
→ Ссылка