使用正则表达式计算对象中的数组项

时间:2017-11-23 00:51:50

标签: javascript regex object count

所以我有一个对象:

   var data = {
      "movies": {
        "first": {
          "title": "Bruce Almigthy",
          "actors": ["Jim Carrey", "Morgan Freeman", "Jennifer Aniston"],
          "year": "2003"
        },
        "second": {
          "title": "The Truman Show",
          "actors": ["Jim Carrey", "Ed Harris","Morgan Freeman", "Laura Linney"],
          "year": "1998"
        },
        "third": {
          "title": "Ace Ventura",
          "actors": ["Jim Carrey", "Courteney Cox","Ed Harris"],
          "year": "1994"
        }
      }
    };

console.log(data.movies);

我需要找到盯着1部以上电影的演员,以及只在一部电影中出演的演员。我通常用这样的方式处理这类问题:

function countMax(data) { 

    var actors = {}; 

    Object.keys(data.movies).forEach(function (key) { 
        var movie = data.movies[key]; 

        movie.actors.forEach(function (actor) { 
            if (!actors.hasOwnProperty(actor)) actors[actor] = 0; 
            actors[actor]++;    
        }) 

    }) 

    Object.keys(actors).forEach(function (actor) { 

        var count = actors[actor]; 
        if (count > 1) console.log(actor + ' stars in ' + count + ' movies.'); 

    });

}; 

countMax(data);

我想知道是否有不同的方法这样做,可能是通过使用正则表达式或类似的东西?我只是不确定如何“接近”该对象。

3 个答案:

答案 0 :(得分:1)

我不认为这里有很多正则表达式会对你有所帮助,但是你可以通过一些现代Javascript的细节来缩短一些东西。例如,您可以制作演员的地图并计算:

var actor_map = Object.values(data.movies).reduce((a, c) => {
    c.actors.forEach(i => a[i] = a[i] ? a[i]+1 : 1 )
    return a
}, {})

然后你可以过滤计数以获得你想要的任何东西:

var more_that_one = Object.entries(actor_map).filter(([k, v]) => v > 1)
var less_that_one = Object.entries(actor_map).filter(([k, v]) => v == 1)

var data = {
    "movies": {
      "first": {
        "title": "Bruce Almigthy",
        "actors": ["Jim Carrey", "Morgan Freeman", "Jennifer Aniston"],
        "year": "2003"
      },
      "second": {
        "title": "The Truman Show",
        "actors": ["Jim Carrey", "Ed Harris","Morgan Freeman", "Laura Linney"],
        "year": "1998"
      },
      "third": {
        "title": "Ace Ventura",
        "actors": ["Jim Carrey", "Courteney Cox","Ed Harris"],
        "year": "1994"
      }
    }
  };

var actor_map = Object.values(data.movies).reduce((a, c) => {
    c.actors.forEach(i => a[i] = a[i] ? a[i]+1 : 1 )
    return a
}, {})

var more_that_one = Object.entries(actor_map).filter(([k, v]) => v > 1)
var less_that_one = Object.entries(actor_map).filter(([k, v]) => v == 1)

console.log(more_that_one)
console.log(less_that_one)

答案 1 :(得分:0)

你所做的似乎很好,正则表达不是解决所有问题的魔杖。

在这里,我刚刚使用更多的ES6糖修改了你所做的。像Object.values& Object.entries

PS。 hasOwnProperty不是必需的,在使用for in时,您需要在ES5中使用它。 for of现在可以使用..

const data = {
  "movies": {
    "first": {
      "title": "Bruce Almigthy",
      "actors": ["Jim Carrey", "Morgan Freeman", "Jennifer Aniston"],
      "year": "2003"
    },
    "second": {
      "title": "The Truman Show",
      "actors": ["Jim Carrey", "Ed Harris","Morgan Freeman", "Laura Linney"],
      "year": "1998"
    },
    "third": {
      "title": "Ace Ventura",
      "actors": ["Jim Carrey", "Courteney Cox","Ed Harris"],
      "year": "1994"
    }
  }
};


function countMax(data) { 
  var actors = {}; 
  Object.values(data.movies).forEach(movie => 
    movie.actors.forEach(actor => actors[actor] = (actors[actor] | 0) + 1) 
  ) 
  Object.entries(actors).forEach(([actor, count]) => {
    if (count > 1) console.log(actor + ' stars in ' + count + ' movies.'); 
  });
}; 

countMax(data);

答案 2 :(得分:0)

我想我会稍微重构一下。

var data = {"movies":{"first":{"title":"Bruce Almigthy","actors":["Jim Carrey","Morgan Freeman","Jennifer Aniston"],"year":"2003"},"second":{"title":"The Truman Show","actors":["Jim Carrey","Ed Harris","Morgan Freeman","Laura Linney"],"year":"1998"},"third":{"title":"Ace Ventura","actors":["Jim Carrey","Courteney Cox","Ed Harris"],"year":"1994"}}};

function countMax(data) {
  Array.from(Object.values(data.movies).reduce((m, movie) => {
    movie.actors.forEach(actor => m.set(actor, (m.get(actor) || 0) + 1));
    return m;
  }, new Map()).entries())
    .filter(([_, count]) => count > 1)
    .forEach(([actor, count]) => console.log(actor + ' stars in ' + count + ' movies.'))
}

countMax(data);