patternjavascriptMinor
Multiply all elements in an array except one
Viewed 0 times
elementsallarraymultiplyoneexcept
Problem
The problem is: loop through a list of numbers and for each one of them get the product of all the others and return a new array.
For example in [1,2,3,4,5] the third element should be 40 because 1 × 2 × 4 × 5 = 40
I'm looking for feedback on efficiency and good practices.
For example in [1,2,3,4,5] the third element should be 40 because 1 × 2 × 4 × 5 = 40
I'm looking for feedback on efficiency and good practices.
function main(numbers) {
var result = [];
for (var i in numbers) {
var n = 1;
for (var j in numbers) {
if (i != j) {
n *= numbers[j];
}
}
result.push(n);
}
return result;
}
var a = [2, 6, 9, 31, 55];
console.log(main(a).toString());Solution
What you have shown is an \$O(n^2)\$ solution in that you use nested loops to determine the results.
I would suggest an \$O(2n)\$ approach:
You could probably use for loops instead of
ES6 version:
One could also easily foresee a case where larger arrays could easily hit up against the
I would suggest an \$O(2n)\$ approach:
function main(numbers) {
// one iteration to get product of whole array
var arrayProduct = numbers.reduce(function(product, value) {
return product * value;
}, 1);
// one iteration to map new array values by dividing
// full array product by current value
return numbers.map(function(value) {
return arrayProduct / value;
});
}You could probably use for loops instead of
Array functions to micro-optimize this, but if I put myself into the position of someone who might grade such an algorithmic challenge as this. I would probably be happier to see code like this, as it still meets the requirement to optimize the performance to \$O(2n)\$, while providing code that is more readable. In other words, I would rather see the reduce() and map() calls in a production code base unless I had a use case where I really needed to squeeze every drop of performance out of this function.ES6 version:
const main = (numbers) => {
const arrayProduct = numbers.reduce( (product, value) => product * value, 1);
return numbers.map( (value) => arrayProduct / value );
}One could also easily foresee a case where larger arrays could easily hit up against the
Number.MAX_SAFE_INTEGER value in javascript (\$2exp53\$), so one might consider throwing an error at some point to abort the operation.const main = (numbers) => {
const arrayProduct = numbers.reduce(
(product, value) => {
const product = product * value;
if (product >= Number.MAX_SAFE_INTEGER) {
throw new RangeError('Product has reached Number.MAX_SAFE_INTEGER');
}
return product;
},
1
);
return numbers.map( (value) => arrayProduct / value );
}Code Snippets
function main(numbers) {
// one iteration to get product of whole array
var arrayProduct = numbers.reduce(function(product, value) {
return product * value;
}, 1);
// one iteration to map new array values by dividing
// full array product by current value
return numbers.map(function(value) {
return arrayProduct / value;
});
}const main = (numbers) => {
const arrayProduct = numbers.reduce( (product, value) => product * value, 1);
return numbers.map( (value) => arrayProduct / value );
}const main = (numbers) => {
const arrayProduct = numbers.reduce(
(product, value) => {
const product = product * value;
if (product >= Number.MAX_SAFE_INTEGER) {
throw new RangeError('Product has reached Number.MAX_SAFE_INTEGER');
}
return product;
},
1
);
return numbers.map( (value) => arrayProduct / value );
}Context
StackExchange Code Review Q#160701, answer score: 8
Revisions (0)
No revisions yet.