Javascript Фильтр массив с дубликатами элементов в конкретном случае - PullRequest
0 голосов
/ 02 марта 2019

У меня есть массив имен, у которых есть дубликаты.

let arr = ['John', 'Jack', 'John', 'Jack', 'Jack', 'June', 'June'];

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

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

'John', 'Jack', 'June'

Для этого я объявил объект ni и перебрал arr для добавления свойств к объекту, соответствующему каждому имени;свойство будет содержать значение массива, содержащего каждый индекс, по которому встречается имя.

let ni  = {};

for(let i = 0; i < arr.length; i++) {
  let name = arr[i];
  if(nc.hasOwnProperty(name)) {
    ni[name].push(i);
  } else {
    ni[name] = [i];
  }
}

console.log(ni);
// > Object { John: Array [0, 2], Jack: Array [1, 3, 4], June: Array [5, 6] }

В моей функции Array.filter я проверяю, равен ли индекс элемента индексу 1 свойства объекта, соответствующегос тем же именем.

let newArr = arr.filter(function(name) {
  if(ni.hasOwnProperty(name)) {
    return arr.indexOf(name) === ni[name][1];
  }
});

Это должно вернуть John в index 2, Jack в index 3 и June в index 6 в новый массив.

Однако это не сработало.Запись newArr на консоль приведет к выводу массива, полностью неизменного от оригинала.

> Array ["John", "Jack", "John", "Jack", "Jack", "June", "June"]

Ответы [ 3 ]

0 голосов
/ 02 марта 2019

Я создаю объект вместо массива, потому что он кажется более подходящим для сопоставления имени с индексом второго появления.Это работает следующим образом: indexOf возвращает индекс 1-го вхождения элемента в массиве, поэтому, если indexOf не равно текущему индексу, то это 2-е или более позднее вхождение, тогда я проверяю, не существует ли имя ввозвращаемый объект, поэтому я знаю, что это не 3-й или более поздний случай.

let arr = ['John', 'Jack', 'John', 'Jack', 'Jack', 'June', 'June'];
let newObj = arr.reduce(function(acc, cur, idx) {
  if (arr.indexOf(cur)!==idx && !acc[cur]) { acc[cur] = idx; }
	return acc;
}, {});
console.log(newObj);
0 голосов
/ 02 марта 2019

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

const array = ['Jane', 'John', 'Jack', 'John', 'Jack', 'Jack', 'June', 'June'];
const filtered = [];
const count = array.reduce((a, name) => {
  a[name] = a[name] + 1 || 1;
  if(a[name] === 2)
    filtered.push(name)
  
  return a;
}, {});

console.log(filtered)

Или получить ключи счетчика со счетчиком> 1

const array = ['Jane', 'John', 'Jack', 'John', 'Jack', 'Jack', 'June', 'June'],
      count = array.reduce((a, n) => (a[n] = a[n] + 1 || 1, a), {}),
      filtered = Object.keys(count).filter(n => count[n] > 1);
      
console.log(filtered)
0 голосов
/ 02 марта 2019

Вы можете использовать простую логику массива, например, так:

let newArr = arr.filter((e, i) => i == ni[e][1]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...