Карта массива объекта в неповторяющееся значение объекта с использованием JavaScript - PullRequest
0 голосов
/ 02 июля 2018

Я пытаюсь найти способ преобразовать список субъектов в объекте JS, чтобы я мог создать фильтр без повторяющихся значений.

Пока мне удалось отобразить и отфильтровать уникальные значения в два отдельных массива. Код, который мне удалось написать, является базовым (и не решает проблему):

var topic = subject
           .map(function (value) { return value.topic })
           .filter(function (elem, index, self) {
             return index == self.indexOf(elem);
           });

Итак, форма моих предметов такая:

var subjects = [ {
  "topic" : "Social Sciences",
  "subtopic" : "Developmental Issues"
}, {
  "topic" : "Social Sciences",
  "subtopic" : "General"
}, {
  "topic" : "Social Sciences",
  "subtopic" : "General"
}, {
  "topic" : "Social Sciences",
  "subtopic" : "General and Others"
},{
  "topic" : "Social Sciences",
  "subtopic" : "Arts"
},{
  "topic" : "Social Sciences",
  "subtopic" : "History"
}, {
  "topic" : "Arts and Humanities",
  "subtopic" : "History"
}, {
  "topic" : "Arts and Humanities",
  "subtopic" : "Literature"
} ]

И мне нужно создать фильтр, который выглядит следующим образом:

 filter = [{
         name: "Social Sciences",
         {
             subtopic: "Developmental Issues",
             subtopic: "General",
             subtopic: "General and Others",
             subtopic: "Arts",
             subtopic: "History"
         }
     }, {
         name: "Arts and Humanities",
         {
             subtopic: "History",
             subtopic: "Literature"
         }
     }

Ответы [ 4 ]

0 голосов
/ 03 июля 2018

Используйте Array.prototype.reduce для группировки данных по теме, а затем сопоставьте их с Object.keys и Array.prototype.map:

NOTE: вывод подтемы - Array, а не Object, поскольку те же ключи объекта будут перезаписаны.

var subjects = [{"topic":"Social Sciences","subtopic":"Developmental Issues"},{"topic":"Social Sciences","subtopic":"General"},{"topic":"Social Sciences","subtopic":"General"},{"topic":"Social Sciences","subtopic":"General and Others"},{"topic":"Social Sciences","subtopic":"Arts"},{"topic":"Social Sciences","subtopic":"History"},{"topic":"Arts and Humanities","subtopic":"History"},{"topic":"Arts and Humanities","subtopic":"Literature"}];

var datObj = subjects.reduce((all, {topic, subtopic}) => {
  if (!all.hasOwnProperty(topic)) all[topic] = [];
  all[topic].push(subtopic);
  return all;
}, {});

var filter = Object.keys(datObj).map(topic => ({name: topic, subtopic: datObj[topic]}))

console.log(filter);
0 голосов
/ 02 июля 2018

Вы не можете иметь один и тот же ключ несколько раз внутри объекта, поэтому вы можете создать структуру массива для subtopic и вставить туда subtopic, используя reduce:

var subjects = [ {
  "topic" : "Social Sciences",
  "subtopic" : "Developmental Issues"
}, {
  "topic" : "Social Sciences",
  "subtopic" : "General"
}, {
  "topic" : "Social Sciences",
  "subtopic" : "General"
}, {
  "topic" : "Social Sciences",
  "subtopic" : "General and Others"
},{
  "topic" : "Social Sciences",
  "subtopic" : "Arts"
},{
  "topic" : "Social Sciences",
  "subtopic" : "History"
}, {
  "topic" : "Arts and Humanities",
  "subtopic" : "History"
}, {
  "topic" : "Arts and Humanities",
  "subtopic" : "Literature"
} ];

var filter = subjects.reduce(function(acc, subject){
  var accTopic = acc.find(item => item.name === subject.topic);
  if(!accTopic){
    acc.push({'name': subject.topic, 'subtopic': [subject.subtopic]});
    return acc;
 } else {
   accTopic.subtopic.push(subject.subtopic);
   return acc;
 }
},[]);
console.log(filter);
0 голосов
/ 02 июля 2018
let res = subjects.reduce((acc, v, i) => {
    let topic = acc.find(item => item.name == v.topic)
    if (! topic) {
        topic = {name: v.topic, subtopics: []}
        acc.push(topic)
    }
    topic.subtopics.push(v.subtopic)
    return acc
}, [])

Так как вы не можете иметь один и тот же ключ на том же объекте, я создал массив с подтемами, если это может вам помочь.

0 голосов
/ 02 июля 2018

Ключи объекта должны быть уникальными. Вы не можете иметь несколько ключей с одним и тем же именем в одном объекте. Один из вариантов - использовать массив для subtopic.

Используйте reduce, чтобы сгруппировать массив в объект. Используйте new Set() для подтемы, чтобы получить уникальные значения. Используйте Object.values для преобразования объекта в массив.

map массив и использование синтаксиса расширения для преобразования набора в массив.

var subjects = [{"topic":"Social Sciences","subtopic":"Developmental Issues"},{"topic":"Social Sciences","subtopic":"General"},{"topic":"Social Sciences","subtopic":"General"},{"topic":"Social Sciences","subtopic":"General and Others"},{"topic":"Social Sciences","subtopic":"Arts"},{"topic":"Social Sciences","subtopic":"History"},{"topic":"Arts and Humanities","subtopic":"History"},{"topic":"Arts and Humanities","subtopic":"Literature"}];

var filter = Object.values(subjects.reduce((c, v) => {
  c[v.topic] = c[v.topic] || {name: v.topic,subtopic: new Set()};
  c[v.topic].subtopic.add(v.subtopic);
  return c;
}, {})).map(o => {
  o.subtopic = [...o.subtopic];
  return o;
})

console.log(filter);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...