Добавление уникальных объектов в массив в JavaScript - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть объект Filter, в котором хранится информация о типах автомобилей. Эта информация извлекается через AJAX, и при первом вызове ajax объекты 0-10 создаются и помещаются в массив. При втором вызове ajax возвращается больше типов автомобилей и добавляются в массив.

Мой вопрос: Я хочу добавлять объекты в массив только с уникальной меткой. Поэтому для следующего вызова AJAX я хочу добавить в массив только объект с меткой «Hybrid». Вот что у меня есть, по какой-то причине метод indexOf не работает и добавляет в массив все новые типы автомобилей с одинаковыми метками.

Код:

var filter_object = Object.create(Filter);
filter_object.init(label, $(this).val());


if (types.indexOf(filter_object.label) == -1)
   types.push(filter_object);


  var Filter = {
     init: function (label, value) {
        this.label = label;
        this.value = value;
     }
  };

Образцы объектов:

0:   {label: "All Car Types", value: "on"}
1:   {label: "Small Cars", value: "CCAR,ECAR,CDAR,EDAR"}
2:   {label: "Medium Cars", value: "ICAR,SCAR,IDAR"}
3:   {label: "Large Cars", value: "FCAR,PCAR,FDAR"}
4:   {label: "SUVs & Crossovers", value: "IFAR,SFAR,CFAR,RFAR,FFAR,PFAR"}
5:   {label: "Vans", value: "MVAR,RVAR,FVAR"}
6:   {label: "Luxury", value: "LCAR,LDAR"}
7:   {label: "Convertibles", value: "STAR"}
8:   {label: "Sports", value: "SSAR"}
9:   {label: "Commercial", value: "SKAR"}
10:  {label: "Specialty", value: "XXAR"}


// Next AJAX Call
11: {label: "All Car Types", value: "on"}
12: {label: "Small Cars", value: "ECAR,MCAR,CCAR,CDAR,EDAR"}
13: {label: "Hybrids", value: "ICAH,FCAH"}

Ответы [ 3 ]

0 голосов
/ 27 апреля 2018

Вы можете создать новый массив всех ваших существующих меток в качестве поиска, а затем вызвать .reduce для вашего входящего массива следующим образом:

const existingLabels = existing.map(item => item.label);

const updated = newItems.reduce((all, item) => {
  if (!existingLabels.includes(item.label))
      all.push(item);

  return all;
}, existing);
0 голосов
/ 27 апреля 2018

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

const combineValues = (v1, v2) => {
  const a1 = v1.split(','), a2 = v2.split(',');
  return a1.concat(a2.filter(v => !(a1.includes(v)))).join(',')
}
// combineValues('a,b,c,d', 'a,b,c,e,f') //=> "a,b,c,d,e,f"

const combineTypes = (types, newTypes) => {
  return types.map(type => {
    const matchType = newTypes.find(t => t.label === type.label) || type
    return {label: type.label, value: combineValues(type.value, matchType.value)}
  }).concat(newTypes.filter(type => types.every(t => t.label !== type.label)))
}


const types = [{"label": "All Car Types", "value": "on"}, {"label": "Small Cars", "value": "CCAR,ECAR,CDAR,EDAR"}, {"label": "Medium Cars", "value": "ICAR,SCAR,IDAR"}, {"label": "Large Cars", "value": "FCAR,PCAR,FDAR"}, {"label": "SUVs & Crossovers", "value": "IFAR,SFAR,CFAR,RFAR,FFAR,PFAR"}, {"label": "Vans", "value": "MVAR,RVAR,FVAR"}, {"label": "Luxury", "value": "LCAR,LDAR"}, {"label": "Convertibles", "value": "STAR"}, {"label": "Sports", "value": "SSAR"}, {"label": "Commercial", "value": "SKAR"}, {"label": "Specialty", "value": "XXAR"}]
const newTypes = [{"label": "All Car Types", "value": "on"}, {"label": "Small Cars", "value": "ECAR,MCAR,CCAR,CDAR,EDAR"}, {"label": "Hybrids", "value": "ICAH,FCAH"}]


const updated = combineTypes(types, newTypes)
console.log(updated)

Обратите внимание, что это объединяет значения внутри "Маленьких машин" и добавляет "Гибриды". Он не изменяет никакие ваши данные, но создает новый массив с новыми объектами.

Для простоты кода включена некоторая глупая неэффективность. Когда не найдено подходящего нового типа, мы вызываем combineValues для типа и самого себя, что явно бесполезно. Хотя это было бы несложно исправить, код был бы несколько уродливее. Учитывая вероятное количество элементов, я не могу представить, что это будет проблематично.

0 голосов
/ 26 апреля 2018

Вы должны использовать .some из es6, как

if (!types.some(e=> e.label === filter_object.label))
 types.push(filter_object);

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

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