Какой вариант поиска уникального элемента в массиве лучше по производительности в целом?
Решав задачу меня занял вопрос: какой вариант поиска уникального элемента в целочисленном массиве размером больше 2 элементов (один нечетный или один четный) будет лучше по производительности:
- Два вызова
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];
}
- Проход
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];
}
}
}