Произведение всех других чисел в массиве - PullRequest
0 голосов
/ 11 марта 2019

У меня есть функция, которая принимает массив чисел в качестве аргумента.Я хочу вернуть новый массив с произведениями каждого числа, кроме числа с текущим индексом.

Например, если у arr было 5 индексов, и мы создавали значение для индекса 1, чиселпри индексах 0, 2, 3 и 4 умножается.

Вот код, который я написал:

function getProducts(arr) {
let products = [];
for(let i = 0; i < arr.length; i++) {
    let product = 0;
    for(let value in arr.values()) {
      if(value != arr[i]) {
        product *= value;
      }
    }
    products.push(product);
}
return products;
}
getProducts([1, 7, 3, 4]);
// Output ➞ [0, 0, 0, 0]
// Expected output ➞ [84, 12, 28, 21]

Как видите, требуемый вывод не актуализируется.Я провел некоторые эксперименты, и оказалось, что второй цикл for действительно никогда не запускается, так как любой код, помещенный в блок, не выполняется:

function getProducts(arr) {
let products = [];
for(let i = 0; i < arr.length; i++) {
    let product = 0;
    for(let value in arr.values()) {
      console.log('hello!');
      if(value != arr[i]) {
        product *= value;
      }
    }
    products.push(product);
}
return products;
}
getProducts([1, 7, 3, 4]);
// Output ➞ 
// Expected Output ➞ 'hello!'

Что не так с моим кодом?

Ответы [ 4 ]

2 голосов
/ 11 марта 2019

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

function getProducts(array) {
    var product = array.reduce((a, b) => a * b, 1);
    return array.map(p => product / p);
}

console.log(getProducts([1, 7, 3, 4]));

Более надежный подход с массивом с одним нулем. Если массив имеет более одного нуля, все продукты равны нулю.

Приведенный ниже подход заменяет значение в индексе на единицу.

function getProducts(array) {
    return array.map((_, i, a) => a.reduce((a, b, j) => a * (i === j || b), 1));
}

console.log(getProducts([1, 7, 0, 4]));
console.log(getProducts([1, 7, 3, 4]));
1 голос
/ 11 марта 2019

Лучший способ сделать это - получить общий продукт и использовать map(), чтобы разделить total с каждым значением

function getProducts(arr){
  let total = arr.reduce((ac,a) => ac * a,1);
  return arr.map(x => x === 0 ? total : total/x);
}
console.log(getProducts([1, 7, 3, 4]))
1 голос
/ 11 марта 2019

Вам просто нужно изменить ключевое слово in на ключевое слово of.Не то же самое for..in, чем for..of.

arr.values() возвращает итератор, который должен повторяться с ключевым словом of.

Кроме того, если product = 0, тогда все ваши умножения будут возвращать 0.

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

И теперь, говоря о передовых методах, немного странно, что сначала вы перебираете массив с циклом for(var i..., а второйраз вы делаете это с for...in/of.

Я исправил код для вас:

function getProducts(arr) {
    let products = [];
    for(let i = 0; i < arr.length; i++) {
        let product = 1;
        for(let ii = 0; ii < arr.length; ii++) {
            if(i != ii) {
                product *= arr[ii];
            }
        }
        products.push(product);
    }
    return products;
}
0 голосов
/ 11 марта 2019

Объяснение: замените число в i на 1 , чтобы оно не не мешало умножению. Кроме того, примените заливка к копии из a , следовательно, [... a]

console.log( [2,3,4,5].map( (n,i,a) => [...a].fill(1,i,i+1).reduce( (a,b) => a*b ) ) )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...