JavaScript 对象无法被其识别 属性

JavaScript Objects is not recognised by it's property

我的程序非常简单 - 它应该将电影保存在数组中,然后以 JSON 格式打印它们。 问题在于 'contains()' 方法(我认为)。它适用于一个命名的电影,但当名称包含空格时它 returns null。这是代码。

function movieDirectors(array) {
  let movies = [];

  class Movie {
    constructor(name, director, date) {
      this.name = name;
      this.director = director;
      this.date = date;
    }
  }
  let contains = function (movieName) {
    let movie = null;
    movies.forEach(m => m.name === movieName ? movie = m : movie = null);
    return movie;
  }

  for (let i = 0; i < array.length; i++) {
    let command = array[i].split(' ');

    if (command.includes('addMovie')) {
      let name = command.slice(1, command.length).join(' ');
      movies.push(new Movie(name, null, null));
    } else if (command.includes('directedBy')) {
      let name1 = command.slice(0, command.indexOf('directedBy')).join(' ');
      if (contains(name1) !== null) {
        let movie = contains(name1);
        movie.director = command.slice(command.indexOf('directedBy') + 1, command.length).join(' ');
      }
    } else if (command.includes('onDate')) {
      let name2 = command.slice(0, command.indexOf('onDate')).join(' ');
      if (contains(name2) !== null) {
        let movie = contains(name2);
        movie.date = command.slice(command.indexOf('onDate') + 1, command.length).join(' ');
      }
    }
  }
  movies.forEach(m => m.director != null && m.name != null && m.date != null ? console.log(JSON.stringify(m)) : null);
}

movieDirectors([
    'addMovie Fast and Furious',
    'addMovie Godfather',
    'Godfather directedBy Francis Ford Coppola',
    'Godfather onDate 29.07.2018',
    'Fast and Furious onDate 30.07.2018',
    'Fast and Furious directedBy Rob Cohen']);

输出必须是这样的:

{"name":"Fast and Furious","date":"30.07.2018","director":"Rob Cohen"}
{"name":"Godfather","director":"Francis Ford Coppola","date":"29.07.2018"}

我在 JavaScript 语言方面还很新手,如果能帮助我理解这门语言的这些优点,我将不胜感激。

问题是您在 contains() 中制作 forEach 的方式。

你有:

movies.forEach(m => m.name === movieName ? movie = m : movie = null);

您的 movies 数组首先填充 Fast and Furious,然后填充 Godfather。在 forEach 的第一次迭代中,它将测试 Fast and Furious 并发现它等于 movieName,因此 movie = m 您的代码将使用正确的对象设置 movie。在第二次迭代中,它将 运行 与 Godfather 进行相同的测试,并发现它与 movieName 不同,因此 movie = null 您的代码将清除 movie,这就是错误。相反,让您的代码在 m.name === movieName 为 false 时不执行任何操作。所以:

movies.forEach(m => m.name === movieName ? movie = m : null);

这是完整的工作片段:

function movieDirectors(array) {
  let movies = [];

  class Movie {
    constructor(name, director, date) {
      this.name = name;
      this.director = director;
      this.date = date;
    }
  }
  let contains = function (movieName) {
    let movie = null;
    movies.forEach(m => m.name === movieName ? movie = m : null); // The problem was here
    return movie;
  }

  for (let i = 0; i < array.length; i++) {
    let command = array[i].split(' ');

    if (command.includes('addMovie')) {
      let name = command.slice(1, command.length).join(' ');
      movies.push(new Movie(name, null, null));
    } else if (command.includes('directedBy')) {
      let name1 = command.slice(0, command.indexOf('directedBy')).join(' ');
      if (contains(name1) !== null) {
        let movie = contains(name1);
        movie.director = command.slice(command.indexOf('directedBy') + 1, command.length).join(' ');
      }
    } else if (command.includes('onDate')) {
      let name2 = command.slice(0, command.indexOf('onDate')).join(' ');
      if (contains(name2) !== null) {
        let movie = contains(name2);
        movie.date = command.slice(command.indexOf('onDate') + 1, command.length).join(' ');
      }
    }
  }
  movies.forEach(m => m.director != null && m.name != null && m.date != null ? console.log(JSON.stringify(m)) : null);
}

movieDirectors([
    'addMovie Fast and Furious',
    'addMovie Godfather',
    'Godfather directedBy Francis Ford Coppola',
    'Godfather onDate 29.07.2018',
    'Fast and Furious onDate 30.07.2018',
    'Fast and Furious directedBy Rob Cohen']);

由于您的问题主要与字符串解析有关,您可以使用如下正则表达式来解决它:

const input = [
  'addMovie Fast and Furious',
  'addMovie Godfather',
  'Godfather directedBy Francis Ford Coppola',
  'Godfather onDate 29.07.2018',
  'Fast and Furious onDate 30.07.2018',
  'Fast and Furious directedBy Rob Cohen'
];

const output = input.reduce((acc, cur) => {
    const parseAddMovie = /^addMovie\s(.+)/.exec(cur);
    if (parseAddMovie) {
      const [, name] = parseAddMovie;
      acc.push({ name });
      return acc;
    }
    const parseDirectedBy = /(.+)\sdirectedBy\s(.+)/.exec(cur);
    if (parseDirectedBy) {
      const [, name, director] = parseDirectedBy;
      const found = acc.find(x => x.name === name);
      found && (found.director = director);
      return acc;
    }
    const parseOnDate = /(.+)\sonDate\s(.+)/.exec(cur);
    if (parseOnDate) {
      const [, name, date] = parseOnDate;
      const found = acc.find(x => x.name === name);
      found && (found.date = date);
      return acc;
    }
  }, []);

console.log(output);

函数 contains 预计会停止,并且 return 会在找到具有给定名称的电影时停止。

它将起作用:

let contains = function (movieName) {
    return movies.find(m => m.name === movieName);
}