Multiply all elements in an array except one 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.



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());
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:

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) =&gt; {
    const arrayProduct = numbers.reduce( (product, value) =&gt; product * value, 1);
    return numbers.map( (value) =&gt; 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) =&gt; {
    const arrayProduct = numbers.reduce(
        (product, value) =&gt; {
            const product = product * value;
            if (product &gt;= Number.MAX_SAFE_INTEGER) {
                throw new RangeError('Product has reached Number.MAX_SAFE_INTEGER');
            }
            return product;
        },
        1
    );
    return numbers.map( (value) =&gt; arrayProduct / value );
}