2016-10-03 1 views
2

У меня есть объект, который содержит два массива элементов. Эти элементы структурированы одинаково, и каждый из них имеет «технический» атрибут, который представляет собой массив строк. Я хочу напечатать массив всех возможных уникальных строк, которые отображаются во всех объектах. Решение, которое я включил ниже, работает, но мне интересно, есть ли более лаконичный способ выполнить эту задачу с помощью lodash?Есть ли более простой способ построить массив уникальных значений из нескольких коллекций объектов с lodash?

var data = { 
    "sitesA" : [ 
     { 
      "name": "Website Alpha", 
      "tech": ["SASS", "Foundation", "jQuery"] 
     }, 
     { 
      "name":"Website Beta", 
      "tech":["SASS","AngularJS"] 
     }, 
     { 
      "name":"Website Charlie", 
      "tech":["CSS","WordPress"] 
     } 
    ], 
    "sitesB" : [ 
     { 
      "name":"OtherSite", 
      "tech":["CSS","jQuery"] 
     }, 
     { 
      "name":"Bears", 
      "tech":["SASS","AngularJS"] 
     }, 
     { 
      "name":"Taco Time", 
      "tech":["CSS", "ASP", "SQL"] 
     } 
    ] 
} 

var tech = []; 

_.each(data,function(collection){ 
    _.each(collection,function(item){ 
     _.each(item.tech, function(value){ 
      tech.push(value); 
     }); 
    }); 
}); 

console.log(_.uniq(tech)); 
//^returns desired result of: ["SASS", "Foundation", "jQuery", "AngularJS", "CSS", "WordPress", "ASP", "SQL"] 
+0

Для справки: посмотрите, как использовать ES6 'new Set ([])' для получения уникальных значений: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set – colecmc

ответ

2
var data = { "sitesA": [{ "name": "Website Alpha", "tech": ["SASS", "Foundation", "jQuery"] }, { "name": "Website Beta", "tech": ["SASS", "AngularJS"] }, { "name": "Website Charlie", "tech": ["CSS", "WordPress"] }], "sitesB": [{ "name": "OtherSite", "tech": ["CSS", "jQuery"] }, { "name": "Bears", "tech": ["SASS", "AngularJS"] }, { "name": "Taco Time", "tech": ["CSS", "ASP", "SQL"] }] }, 
tech = []; 

    _.each(data , function(collection){ 
     tech.push(_.map(collection,'tech')); 
    }); 

console.log(_.uniq(_.flattenDeep(tech))); 
2

Как насчет этого?

var tech = _.uniq(_.reduce(data, function (memo, collection) { 
    return memo.concat(_.flatten(_.map(collection, _.partial(_.get, _, 'tech')))); 
}, [])); 

Объяснения будет выглядеть следующим образом:

  1. Сократить массив в новый, который создается «получение» Техническое свойства его внутренних компонентов.
  2. В связи с тем, что «технология» является массивом, если вы не применять flatten, вы получите матрицу (то, что мы не хотим, так что мы придавить 'массив)
  3. Get избавиться от дублирующих элементов с использованием _.uniq
+0

Я закончил тем, что решил (ответить suzo предоставил) (http://stackoverflow.com/a/39840154/1608016) ради простоты, но мне очень нравится этот ответ и ценю, что вы тратите время, чтобы пройти через него шаг за шагом step :) – Brice

+0

Спасибо, @briceshatzer ценят это :) – acontell

1

С ES6, вы могли бы использовать Set

var data = { "sitesA": [{ "name": "Website Alpha", "tech": ["SASS", "Foundation", "jQuery"] }, { "name": "Website Beta", "tech": ["SASS", "AngularJS"] }, { "name": "Website Charlie", "tech": ["CSS", "WordPress"] }], "sitesB": [{ "name": "OtherSite", "tech": ["CSS", "jQuery"] }, { "name": "Bears", "tech": ["SASS", "AngularJS"] }, { "name": "Taco Time", "tech": ["CSS", "ASP", "SQL"] }] }, 
 
    techSet = new Set; 
 

 
Object.keys(data).forEach(k => 
 
    data[k].forEach(o => 
 
     o.tech.forEach((new Set).add.bind(techSet)))); 
 

 
console.log([...techSet]);

Смежные вопросы