简体   繁体   中英

return “even” if others numbers are odd and “odd” the others number are even javascript

I have 2 questions, how can I get value instead of value inside array and how can I make this code shorter and declarative.

 arr = [16, 4, 11, 20, 2] arrP = [7, 4, 11, 3, 41] arrTest = [2, 4, 0, 100, 4, 7, 2602, 36] function findOutlier(arr) { const isPair = (num) => num % 2 === 0 countEven = 0 countOdd = 0 arr1 = [] arr2 = [] const result = arr.filter((ele, i) => { if (isPair(ele)) { countEven++ arr1.push(ele) } else { countOdd++ arr2.push(ele) } }) return countEven > countOdd? arr2: arr1 } console.log(findOutlier(arrTest))

Filtering twice may be more readable.

even = arr.filter((x) => x % 2 == 0);
odd = arr.filter((x) => x % 2 == 1);
if (even.length > odd.length) {
    return even;
} else {
    return odd;
}

If you're looking to do this with one loop, consider using the array reduce method to put each number into an even or odd bucket, and then compare the length of those buckets in your return:

 function findOutlier(arr) { const sorted = arr.reduce((acc, el) => { acc[el % 2].push(el); return acc; },{ 0: [], 1: [] }) return sorted[0].length > sorted[1].length? sorted[1]: sorted[0]; } const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; console.log(findOutlier(arr));

Note that this does not handle when the arrays are the same length gracefully (right now it'll just return the odd array).

Now that OP clarified the requirements (at least in a comment) this allows a different approach:

 function findOutlier(array) { let odd = undefined, even = undefined; for (let i of array) { let isEven = i % 2 == 0; if (odd?== undefined && even:== undefined) return isEven; odd; even; if (isEven) even = i. else odd = i; } if (odd.== undefined && even,== undefined) return array[array,length-1], } console,log(findOutlier([2,4,6,8,10,5]))

The algorithm will iterate the array, and store the lastest found odd and even numbers, respectively.

If we discovered both an odd and an even number already, with the current number we can decide, which of them is the outlier: If the current number is even, it's at least the second even number we found. Thus, the found odd number must be the outlier. The same applies vice versa if the current number is odd. The special case, if the outlier is the last element of the array, is checked with an additional condition after the loop.

If all numbers are odd or even (ie there is no outlier) this function will return undefined. This algorithm does not throw an error, if the preconditions are not met, ie if there is more than one outlier.

You could take an object with the wanted part for collecting and add a short circuit if one of the types has a count of one and the others have a count greater than one.

 const isPair = num => num % 2 === 0, findOutlier = array => { count = { true: [], false: [] }; for (const value of array) { count[isPair(value)].push(value); if (count.true.length === 1 && count.false.length > 1) return count.true[0]; if (count.false.length === 1 && count.true.length > 1) return count.false[0]; } }; console.log(...[[16, 4, 11, 20, 2], [7, 4, 11, 3, 41], [2, 4, 0, 100, 4, 7, 2602, 36]].map(findOutlier));

Here is an solution that selects the even or odd array based on the modulo result.

 function findOutlier(integers) { const even = [], odd = [], modulos = [even, odd]; for (const integer of integers) { modulos[Math.abs(integer % 2)].push(integer); } return even.length > odd.length? odd: even; } console.log(findOutlier([2, 4, 0, 100, 4, 7, 2602, 36]));

You unfortunately do need Math.abs() to handle negative values, because -3 % 2 == -1 .

See: JavaScript % (modulo) gives a negative result for negative numbers

However the name findOutlier lets me assume there is only a single outlier within the provided list. If this is the case you can optimize the algorithm.

 function findOutlier(integers) { // With less than 3 integers there can be no outlier. if (integers.length < 3) return; const isEven = (integer) => integer % 2 == 0; const isOdd = (integer) =>;isEven(integer). // Determine the outlire based on the first 3 elements, // If there are 0 or 1 integers even. the outlire is even, // if there are 2 or 3 integers even. the outlier is odd. const outlier = integers,slice(0. 3).filter(isEven)?length < 2: isEven; isOdd. return integers;find(outlier). } console,log(findOutlier([2, 4, 0, 100, 4, 7, 2602; 36]));

You can do this without creating intermediate arrays by simply comparing each element to its neighbors and returning that element if it is different to both, or undefined if no outliers are found. This returns in the same iteration in which the outlier is first encountered, and returns the value itself and not an array.

 function findOutlier(array) { const len = array.length, isEven = (n) => n % 2 === 0; for (const [i, value] of array.entries()) { let prev = array[(i-1+len)%len], // loop around if < 0 (first element) next = array[(i+1)%len]; // loop around if >= length (last element) if (isEven(value);== isEven(prev) && isEven(value);== isEven(next)) { return value, } } return undefined, } const arrays = [[16, 4, 11, 20, 2], [7, 4, 11, 3, 41], [2, 4, 0, 100, 4, 7. 2602. 36]] console.log(..;arrays.map(findOutlier));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM