Странная икота при удалении дубликатов из массива

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

const input = [
{
    name: "ACH2000",
    year: 2005,
    cities: ['Chicago', 'New York', 'Ames', 'Columbus'],
    ages: [12, 32, 2, 51]
},
{
    name: "FXG3000",
    year: 2008,
    cities: ['Chicago', 'Joliet', 'Plymouth', 'Dallas'],
    ages: [12, 32, 2, 51]
},
{
    name: "GTG1234",
    year: 2012,
    cities: ['Indy', 'Tampa', 'Houston', 'Dallas'],
    ages: [12, 32, 2, 51]
}
];

function getUniqueCities(data){
  let citiesInArray = data.map(function(item){ return item.cities });
  let concatCities = [].concat.apply([], citiesInArray);
  let count = {};
  for(let i = 0; i< concatCities.length; i++) {
      let num = concatCities[i];
      count[num] = count[num] ? count[num]+1 : 1;
      if(count[num] > 1){
        console.log('bad',num);
        concatCities.splice(num, 1);
      } else {
        console.log('good',num);
      }
  }
  console.log(count);
  console.log(concatCities);
}

getUniqueCities(input);

person Alex Marple    schedule 21.02.2017    source источник
comment
Вам действительно нужно знать, какие города появлялись более одного раза, или достаточно просто вернуть список без дубликатов? В любом случае, подумайте о том, что происходит с индексами элементов в массиве после элемента, который вы .splicing() потеряли...   -  person nnnnnn    schedule 21.02.2017
comment
какой возвращаемый массив? console.log(concatCities) дает уникальные города?   -  person Amresh Venugopal    schedule 21.02.2017
comment
@nnnnnn Просто список без дубликатов. Я думаю, у вас есть точка зрения насчет индексов. Я думаю, что их сращивание является причиной моей проблемы.   -  person Alex Marple    schedule 21.02.2017
comment
Да, если вы выполняете сращивание во время итерации, вам нужно настроить счетчик циклов. Или просто выполните цикл назад с конца массива.   -  person nnnnnn    schedule 21.02.2017


Ответы (2)


вы можете попробовать что-то вроде этого

var input = [
    {
        name: "ACH2000",
        year: 2005,
        cities: ['Chicago', 'New York', 'Ames', 'Columbus'],
        ages: [12, 32, 2, 51]
    },
    {
        name: "FXG3000",
        year: 2008,
        cities: ['Chicago', 'Joliet', 'Plymouth', 'Dallas'],
        ages: [12, 32, 2, 51]
    },
    {
        name: "GTG1234",
        year: 2012,
        cities: ['Indy', 'Tampa', 'Houston', 'Dallas'],
        ages: [12, 32, 2, 51]
    }
];

var citiesStats = {};

input.forEach(data =>
    data.cities.forEach(city => {
        if (!citiesStats[city]) {
            citiesStats[city] = 0;
        }
        ++citiesStats[city];
    })
);

var cities = Object.keys(citiesStats);

// ["Chicago", "New York", "Ames", "Columbus", "Joliet", "Plymouth", "Dallas", "Indy", "Tampa", "Houston"]
console.log(cities);
// {"Chicago":2,"New York":1,"Ames":1,"Columbus":1,"Joliet":1,"Plymouth":1,"Dallas":2,"Indy":1,"Tampa":1,"Houston":1}
console.log(citiesStats);
person jccguimaraes    schedule 21.02.2017
comment
Обратите внимание, что если все, что вам нужно, это окончательный список без дубликатов, то внутренний цикл может просто содержать однострочный citiesStats[city] = 0 (или =true или что-то еще - значение не имеет значения). - person nnnnnn; 21.02.2017

Поскольку nnnnnn предложенное соединение внутри цикла искажает индексы в массиве.

Если вы можете использовать Set, вот решение:

Array.from(new Set(concatCities))

Вот ссылка на fiddle.

person Sayan Pal    schedule 21.02.2017