【问题标题】:Push value to object if key already exists during Array.map如果在 Array.map 期间键已经存在,则将值推送到对象
【发布时间】:2019-05-04 05:09:37
【问题描述】:

我有一个如下所示的数组:

let movies = [
  'terminator.1',
  'terminator.2',
  'terminator.3',
  'harry-potter.1',
  'harry-potter.3',
  'harry-potter.2',
  'star-wars.1'
]

我想要一个这样的对象:

{
  "terminator": [1,2,3],
  "harry-potter": [1,2,3],
  "star-wars": [1]
}

到目前为止,我能够拥有这样的对象

{
  { terminator: [ '1' ] },
  { terminator: [ '2' ] },
  { terminator: [ '3' ] },
  { 'harry-potter': [ '1' ] },
  { 'harry-potter': [ '3' ] },
  { 'harry-potter': [ '2' ] },
  { 'star-wars': [ '1' ] }
}

我想知道是否有一种方法可以在生成对象时检查 Array.map 是否已经存在某个键,以及是否可以将值推送到相应的数组而不是创建一个新的键值对。

这是我目前用于解决方案的代码。提前致谢。

let movies = [
  'terminator.1',
  'terminator.2',
  'terminator.3',
  'harry-potter.1',
  'harry-potter.3',
  'harry-potter.2',
  'star-wars.1'
]

let t = movies.map(m => {
  let [name, number] = [m.split('.')[0],m.split('.')[1]]
  return {[name]: [number]}
})

console.log(t)

【问题讨论】:

    标签: javascript arrays object array-map array-reduce


    【解决方案1】:

    您可以使用单个Array.reduce 和一个array destructuring 来完成此操作,以获得key/value 组合:

    let movies = [ 'terminator.1', 'terminator.2', 'terminator.3', 'harry-potter.1', 'harry-potter.3', 'harry-potter.2', 'star-wars.1' ]
    
    const result = movies.reduce((r,c) => {
      let [k,v] = c.split('.')
      r[k] = [...r[k] || [], +v]
      return r
    },{})
    
    console.log(result)

    【讨论】:

    • 这按预期工作并且喜欢 es6 功能。我会将@ibrahim 的答案标记为正确的解决方案,因为他是第一个做出回应的人,这很好,但非常感谢!
    【解决方案2】:

    这是Array#reduce 的工作,而不是Array#map

    let t = movies.reduce((acc, movie) => {             // for each movie in movies
       let [name, number] = movie.split('.');           // split the movie by "." and store the first part in name and the second in number
       if(acc[name]) {                                  // if the accumulator already has an entry for this movie name
          acc[name].push(number);                       // then push this movie number into that entry's array
       } else {                                         // otherwise
          acc[name] = [number];                         // create an entry for this movie name that initially contains this movie number
       }
       return acc;
    }, Object.create(null));                            // Object.create(null) is better than just {} as it creates a prototypeless object which means we can do if(acc[name]) safely
    

    注意:如果您想将数字强制转换为实际数字而不是将它们保留为字符串,则使用一元 + 隐式转换它们:+number

    示例:

    let movies = [ 'terminator.1', 'terminator.2', 'terminator.3', 'harry-potter.1', 'harry-potter.3', 'harry-potter.2', 'star-wars.1' ];
    
    let t = movies.reduce((acc, movie) => {
       let [name, number] = movie.split(".");
       if(acc[name]) {
          acc[name].push(number);
       } else {
          acc[name] = [number];
       }
       return acc;
    }, Object.create(null));
    
    console.log(t);

    【讨论】:

    • 这正是我想要的!谢谢。
    【解决方案3】:

    const movies = ['terminator.1', 'terminator.2', 'terminator.3', 'harry-potter.1', 'harry-potter.3', 'harry-potter.2', 'star-wars.1']
    
    const moviesMap = {}
    
    movies.forEach(data => {
      const [title, id] = data.split('.')
      if (moviesMap[title]) {
        moviesMap[title].push(id)
      } else {
        moviesMap[title] = [id]
      }
    })
    
    console.log(moviesMap)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-12
      • 2014-12-07
      相关资源
      最近更新 更多