Javascript forEach l oop не продолжится до следующей итерации - PullRequest
2 голосов
/ 10 июля 2020

Я пытаюсь решить эту задачу, когда функция должна возвращать значение индекса элемента, когда сумма значений с обеих сторон элемента равна. Например, [1,2,3,4,3,2,1] должен вернуть 3, так как по другую сторону от «4» значения складываются с 6 (1 + 2 + 3) и (3 + 2 + 1). Также, если такого значения нет, функция должна вернуть -1.

function findEvenIndex(arr) {
  arr.forEach((element, index) => {
    let a = arr.splice(index + 1, arr.length); //array of values after current value
    let b = arr.splice(arr[0], index); //array of values before current value
    let suma = a.reduce((accumulator, currentValue) => { //Sum of array of after values
      return accumulator + currentValue;
    }, 0);
    let sumb = b.reduce((accumulator, currentValue) => { //Sum of array of before values
      return accumulator + currentValue;
    }, 0);
    if (suma === sumb) {  //comparing the two sums to check if they are equal
      return index;
    };
  });
};

Насколько я понимаю, если suma и sumb НЕ равны, то начнется следующая итерация forL oop, однако этого не происходит, и я не могу понять, почему.

Функция должна вернуть -1, если такого значения не существует, я не реализовал эту часть кода в настоящее время.

Спасибо

Ответы [ 4 ]

2 голосов
/ 10 июля 2020

вы должны использовать метод slice вместо splice и возвращать индекс из l oop


function findEvenIndex(arr) {
  
  var result =  -1;
  arr.forEach((element, index) => {
    let a = arr.slice(index + 1);  
    let b = arr.slice(0, index);  
    let suma = a.reduce((accumulator, currentValue) => {
      //Sum of array of after values
      return accumulator + currentValue;
    }, 0);
    let sumb = b.reduce((accumulator, currentValue) => {
      //Sum of array of before values
      return accumulator + currentValue;
    }, 0);
    if (suma === sumb) {
      //comparing the two sums to check if they are equal
        result =   index;
    }
  });
  return result;
}

также вы можете сделать это с помощью метода findIndex

const sum  = (a,b)=> a+b;
const findEvenIndex = (TestArr) =>
  TestArr.findIndex(
    (_, i) =>
      TestArr.slice(0, i).reduce(sum, 0) === TestArr.slice(i + 1).reduce(sum, 0)
  ); ;
2 голосов
/ 10 июля 2020

В вашем коде есть две проблемы:

  1. Как я указал в своем комментарии, Array.prototype.slice мутирует / изменяет массив на месте , что является плохим идея, когда вы одновременно выполняете итерацию по массиву. Поэтому сделайте неглубокую копию массива перед его соединением с помощью оператора распространения, т.е. [...arr].splice()
  2. Вы возвращаетесь из функции foreach, но не возвращаетесь из внешней функции findEvenIndex().

Лучшее решение - просто использовать for l oop: как только индекс найден, мы можем использовать break для короткого замыкания и выхода из l oop, поскольку мы не хочу проводить дальнейший анализ. Мы храним индекс в переменной за пределами for l oop и возвращаем его:

function findEvenIndex(arr) {
  let foundIndex = -1;
  
  for(let index = 0; index < arr.length; index++) {
    const a = [...arr].splice(index + 1, arr.length); //array of values after current value
    const b = [...arr].splice(0, index); //array of values before current value
    
    const suma = a.reduce((accumulator, currentValue) => { //Sum of array of after values
      return accumulator + currentValue;
    }, 0);
    const sumb = b.reduce((accumulator, currentValue) => { //Sum of array of before values
      return accumulator + currentValue;
    }, 0);
    
    if (suma === sumb) {  //comparing the two sums to check if they are equal
      foundIndex = index;
      break;
    };
  };
  
  return foundIndex;
};

console.log(findEvenIndex([1,2,3,4,3,2,1]));
1 голос
/ 10 июля 2020

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

Если индексы равны не по порядку выйти из l oop.

Затем проверьте delta. Если delta равно нулю, верните левый индекс или -1, если разделительный индекс не найден.

function getIndex(array) {
    let delta = 0,
        i = 0,
        j = array.length - 1;

    while (i < j) {    
        if (delta <= 0) {
            delta += array[i++];
            continue;
        }
        delta -= array[j--];
    }
    
    return delta ? -1 : i;
}

console.log(getIndex([1, 2])); // -1
console.log(getIndex([1, 2, 3, 4, 3, 2, 1])); // 3
console.log(getIndex([1, 2, 2, 2, 4, 3, 2, 2])); // 4
1 голос
/ 10 июля 2020

Несколько примечаний. Воспользуйтесь преимуществами встроенного .findIndex(). Используйте slice, так как он возвращает измененную копию массива. slice / splice принимают индексы в качестве аргументов, поэтому не используйте arr[0] в этих методах.

function findEvenIndex(arr) {
  return arr.findIndex((element, index) => {
    let a = arr.slice(index + 1); //array of values after current value
    let b = arr.slice(0, index); //array of values before current value
    let suma = a.reduce((accumulator, currentValue) => { //Sum of array of after values
      return accumulator + currentValue;
    }, 0);
    let sumb = b.reduce((accumulator, currentValue) => { //Sum of array of before values
      return accumulator + currentValue;
    }, 0);
    return suma===sumb;
  });
};
...