Найти количество вхождений строковых элементов в массиве с помощью lodash или underscore js

у меня есть массив следующего формата:

var array = [ 
  { id: '555weibo' },
  { id: '578weibo' },
  { id: '111facebook' },
  { id: '123facebook' },
  { id: '145facebookpage' },
  { id: '145facebookpage' },
  { id: '766facebook' },
  { id: '242facebook' },
  { id: '432twitter' },
  { id: '432exing' }
 ];

мне нужно найти количество вхождений facebook, twitter, xing и weibo внутри этого массива. например:

{
  weibo: 2,
  facebook: 6,
  twitter: 1,
  xing: 1
}

Я искал решение, но ничего не работает.

следующий код не дает ожидаемого результата. Ваша помощь очень ценится. Спасибо.

var filtered = _.map(diff, function(value, key) {
   return { id: key, count:value };
});

3 ответов


С помощью подчеркивания:

var services = ['weibo', 'facebook', 'twitter', 'xing'];
var result = _.map(services, function(service){ 
     var length = _.reject(array, function(el){
           return (el.id.indexOf(service) < 0); 
     }).length; 
     return {id: service, count: length};
});

вот как вы могли бы сделать это с помощью lodash:

_.countBy(array, _.flow(
    _.method('id.replace', /^\d+/, ''),
    _.method('replace', /page$/, '')
));
  • countBy() возвращает объект со значениями counts as. Ключи генерируются переданным обратным вызовом, поэтому здесь вы можете анализировать и управлять ключами, по которым хотите подсчитать.
  • flow () генерирует функцию, обычно для обратных вызовов map() и так далее. В качестве аргументов используется произвольное число функций. Входные данные фильтруются через каждый из них функции и результат возвращаются. Это мощный способ создания обратных вызовов, потому что его легко переставить/добавить/удалить.
  • метод() возвращает функцию, которая вызывается для данного объекта. Здесь вы хотите заменить начальные числа пустой строкой.
  • method() делает то же самое здесь, только удалив page от конца строки. Обратите внимание, как нет id префикс, так как он просто передается результат функции перед ним.

вы должны указать возможные ключи, так как их невозможно угадать в исходном массиве.

вот решение, вам не нужна никакая библиотека:

var filtered = array.reduce(function(m,v){
    for (var k in m) if (~v.id.indexOf(k)) m[k]++;
    return m;
},{facebook:0, weibo:0, twitter:0, xing:0});

демонстрация