Javascript: метод forEach внутри функции? - PullRequest
0 голосов
/ 18 апреля 2020

Я новичок в JavaScript (я использовал python в течение ~ 3 лет, и в настоящее время я пытаюсь освоить основы синтаксиса JS.) Я использую кодовые войны для облегчения обучения. https://www.codewars.com/kata/5bb904724c47249b10000131/train/javascript

Эта проблема дает подсказку

function points(games) {
  // your code here
}

Правила таковы:

if x>y -> 3 points
if x<y -> 0 point
if x=y -> 1 point 

Мой наивный подход заключается в создании функции, которая получает массив в качестве входных данных и применяет метод forEach к каждому элементу в нем. Тем не менее, я вызываю следующую ошибку: Uncaught SyntaxError: Unexpected token 'else'

games = ["0:3","1:2","3:2"]

function points(games){
  let p = 0;
  games.forEach(
    function(game){
    let x = game.split(':')[0];
    let y = game.split(':')[1];
    if(x>y){
      p = p + 3};
    else if(x=y){
      p = p + 1};
    else {
      p = p + 0;
    };
  });
};

Я хотел бы лучше понять (A), почему эта ошибка начинается и (B), как правильно выполнить sh этот эффект.

Редактировать: Скорее всего, мне нужно привести x и y к типу цифр c, однако это не вызывает текущую ошибку.

Ответы [ 5 ]

2 голосов
/ 18 апреля 2020

Что нужно знать о JS, когда вы приходите с Python: современный тип Array имеет много служебных функций , поэтому код вы написанное может быть сделано всего несколькими вызовами, и троичным (который я действительно wi sh Python поддерживает, как и любой другой современный язык)

function score(games = []) {
  // we could manually sum values, or we can use reduce() to do that for us.
  return games.reduce( (tally, game) => tally + calculateScore(game), 0);
}

/**
 * fun fact about JS: functions are "hoisted" i.e. they all get "moved"
 * during initial read-in to the top of the file, with their ordering
 * made entirely irrelevant: any function can have a function body that
 * calls any other function, because they're all at the same declaration level.
 */
function calculateScore(game = "0:0") {
  let [x, y] = game.split(":").map(parseFloat);
  return x > y ? 3 : x < y ? 0 : 1;
}

Это использует некоторые элементарное современное JS:

  • параметры по умолчанию , в основном такие же, как вы использовали бы в Python,
  • функции стрелок которые похожи на лямбды, но также ничем не похожи на них . Хотя об этом очень важно знать, если вы хотите написать современный JS.
  • array.reduce , который может сделать суммирование значений намного проще или намного сложнее, в зависимости от насколько сложен ваш код,
  • parseFloat , который превращает строки в числа с плавающей точкой (забавный факт: каждое число в JS является числом с плавающей точкой, поэтому вы целые числа только от go до 2 ^ 53: прошлое, которое (n+1) - n === 1 больше не имеет места)
  • * троичный оператор , которого Python крайне не хватает.

Также весьма важно: note то, где вы видите parseFloat, действительно происходит, когда array.map вызывает parseFloat с двумя аргументами: элементом и его индексом в массиве. Для parseFloat это нормально, потому что он принимает только один аргумент. Однако, если бы вы наивно использовали parseInt, все было бы go ужасно неправильным: для этого требуется два аргумента , а именно строка и основание.

1 голос
/ 18 апреля 2020

forEach - не лучший подход к этому вопросу. Этот вопрос можно решить с помощью функции Reduce, которая может быть использована для вычисления накопленной суммы для массива.

const games = ["10:3","1:2","3:2", "3:3"]

//forEach approach
function points(games){
  let p = 0;
  games.forEach(game => {
    const [x, y] = game.split(':').map(parseFloat);
    x>y? p+=3 : x===y ? p+=1 : p+=0
  })
  return p
}


//reduce approach
//second parameter in reduce function is the initial value, which is 0 here
function pointsReduce(games){
  const sum = games.reduce((accumulate, game) => {
    const [x, y] = game.split(':').map(parseFloat);
    return accumulate+= x>y? 3 : x===y ? 1 : 0
  },0)
  return sum
}


console.log(points(games))
console.log(pointsReduce(games))
0 голосов
/ 18 апреля 2020

Ошибка, которую вы получаете, вызвана точкой с запятой (;), которую вы ставите в конце if Области действия:

if { ... }; else // unexpected token

LE: также, у вас есть ошибка во второй проверьте, что вы присваиваете значение y для x. В Javascript сравнения выполняются с == или ===.

Чтобы немного расширить сравнения равенств:

  • == попытается привести значения перед выполнением сравнения (например: 1 == '1' => true)

  • === - это оператор строгого сравнения, который будет возвращать true, только если оба операнда имеют одинаковый тип и значение (например: 1 === 1 => true, 1 === '1' => false)

Вот рабочий пример вашего кода:

function points(games) {
  let p = 0;

  games.forEach((game) => {
    let x = game.split(':')[0];
    let y = game.split(':')[1];
    if(x > y) {
      p = p + 3;
    } else if(x === y) {
      p = p + 1;
    } else {
      p = p + 0;
    }
  });
};

Ниже вы найдете несколько других примеров.

  1. Использование расширений массива и отбрасывание ветви, которая добавляет 0 к сумме
function points(coordinates) {
  let p = 0;

  coordinates.forEach((coordinate) => {
    const [x, y] = coordinate.split(':');
    if(x > y) {
      p = p + 3;
    } else if(x === y) {
      p = p + 1;
    }
  });

  return p;
};
Мой любимый подход к читабельности:
const points = (coordinates) =>  coordinates
  .map(coordinate => coordinate.split(':'))
  .reduce((points, [x, y]) => {
    if (x > y) { return points + 3; }
    if (x === y) { return points + 1; }
    return points;
  }, 0); 
0 голосов
/ 18 апреля 2020

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

function points(games) {
  let p = 0;
  games.forEach(
    function(game) {
      // no reason to do work twice, split once
      const parts = game.split(':')
      const x = +parts[0]; // convert to a number
      const y = +parts[1]; // convert to a number
      if (x > y) {
        p = p + 3
      } else if (x === y) { // comparison is == or === and no semicolon
        p = p + 1;
      } else { // <-- we do not add semicolons to the blocks on if/else
        p = p + 0;
      } // <-- we do not add semicolons to the blocks on if/else
    });
  // your function did not return the calculation total
  return p
};

const games = ["0:3", "1:2", "3:2"];
const result = points(games);
console.log(result);
0 голосов
/ 18 апреля 2020

Кажется, вы перепутали фигурные скобки. Они должны быть правы прежде всего:

 if(x>y){
      p = p + 3;
    } else if(x=y){
      p = p + 1;
    } else {
      p = p + 0;
    };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...