Удалить дубликаты из массива объектов с помощью 2 подходящих свойств - PullRequest
0 голосов
/ 23 января 2020

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

var hours_array = [
{day: "Mon", hour_from: "00:00", hour_to: "00:00"},
{day: "Mon", hour_from: "00:00", hour_to: "00:16"},
{day: "Mon", hour_from: "00:00", hour_to: "00:16"},
{day: "Thu", hour_from: "00:00", hour_to: "00:25"},
{day: "Mon", hour_from: "00:00", hour_to: "00:33"},
{day: "Fri", hour_from: "00:00", hour_to: "00:83"},
{day: "Sat", hour_from: "02:00", hour_to: "05:33"},
{day: "Thu", hour_from: "02:00", hour_to: "05:33"},
{day: "Wed", hour_from: "12:00", hour_to: "14:00"},
{day: "Sun", hour_from: "22:25", hour_to: "13:45"}]

for (let i=0; i< hours_array.length; i++){
 for (let j=0; j<=hours_array.length; j++){
  if ((hours_array[i]['hour_from'] == hours_array[j]['hour_from']) && (hours_array[i]['hour_to'] == hours_array[j]['hour_to'])){
  delete hours_array[j];
  }
 }
}

Я думал, что это ошибка с значениями индекса:

enter image description here

Редактировать: Необходимый результат:

var hours_array = [
{day: "Mon", hour_from: "00:00", hour_to: "00:00"},
{day: "Mon", hour_from: "00:00", hour_to: "00:16"},
{day: "Thu", hour_from: "00:00", hour_to: "00:25"},
{day: "Mon", hour_from: "00:00", hour_to: "00:33"},
{day: "Fri", hour_from: "00:00", hour_to: "00:83"},
{day: "Sat", hour_from: "02:00", hour_to: "05:33"},
{day: "Wed", hour_from: "12:00", hour_to: "14:00"},
{day: "Sun", hour_from: "22:25", hour_to: "13:45"}]

Есть предложения? Какой-нибудь более эффективный алгоритм? Спасибо за чтение!

Ответы [ 4 ]

3 голосов
/ 23 января 2020

Вы можете отфильтровать массив с помощью Set.

Если значение ha sh (построено из hour_from и hour_to) находится в установить, элемент отфильтрован. Если нет, то га sh берется в набор и предмет используется.

var getKey = ({ hour_from, hour_to }) => [hour_from, hour_to].join('|'),
    hours_array = [{ day: "Mon", hour_from: "00:00", hour_to: "00:00" }, { day: "Mon", hour_from: "00:00", hour_to: "00:16" }, { day: "Mon", hour_from: "00:00", hour_to: "00:16" }, { day: "Thu", hour_from: "00:00", hour_to: "00:25" }, { day: "Mon", hour_from: "00:00", hour_to: "00:33" }, { day: "Fri", hour_from: "00:00", hour_to: "00:83" }, { day: "Sat", hour_from: "02:00", hour_to: "05:33" }, { day: "Thu", hour_from: "02:00", hour_to: "05:33" }, { day: "Wed", hour_from: "12:00", hour_to: "14:00" }, { day: "Sun", hour_from: "22:25", hour_to: "13:45" }],
    unique = hours_array.filter((s => o => !s.has(getKey(o)) && s.add(getKey(o)))(new Set));

console.log(unique);
.as-console-wrapper { max-height: 100% !important; top: 0; }
2 голосов
/ 23 января 2020

Вы можете go ленивый путь с Array.prototype.reduce() вместе с Array.prototype.find().

const src = [{day:"Mon",hour_from:"00:00",hour_to:"00:00"},{day:"Mon",hour_from:"00:00",hour_to:"00:16"},{day:"Mon",hour_from:"00:00",hour_to:"00:16"},{day:"Thu",hour_from:"00:00",hour_to:"00:25"},{day:"Mon",hour_from:"00:00",hour_to:"00:33"},{day:"Fri",hour_from:"00:00",hour_to:"00:83"},{day:"Sat",hour_from:"02:00",hour_to:"05:33"},{day:"Thu",hour_from:"02:00",hour_to:"05:33"},{day:"Wed",hour_from:"12:00",hour_to:"14:00"},{day:"Sun",hour_from:"22:25",hour_to:"13:45"}],
      dedupe = src.reduce((res, item) => 
        (
          !res.find(({hour_from, hour_to}) => 
            hour_from == item.hour_from && hour_to == item.hour_to) ? 
          res.push(item) : 
          true, res
        ), [])
      
console.log(dedupe)
0 голосов
/ 23 января 2020

Использовать reduce метод с объединением Object.values.

var hours_array = [
  { day: "Mon", hour_from: "00:00", hour_to: "00:00" },
  { day: "Mon", hour_from: "00:00", hour_to: "00:16" },
  { day: "Mon", hour_from: "00:00", hour_to: "00:16" },
  { day: "Thu", hour_from: "00:00", hour_to: "00:25" },
  { day: "Mon", hour_from: "00:00", hour_to: "00:33" },
  { day: "Fri", hour_from: "00:00", hour_to: "00:83" },
  { day: "Sat", hour_from: "02:00", hour_to: "05:33" },
  { day: "Thu", hour_from: "02:00", hour_to: "05:33" },
  { day: "Wed", hour_from: "12:00", hour_to: "14:00" },
  { day: "Sun", hour_from: "22:25", hour_to: "13:45" }
];

const updated = Object.values(
  hours_array.reduce(
    (acc, curr) => ({
      ...acc,
      [`${curr.hour_from}-${curr.hour_to}`]: { ...curr }
    }),
    {}
  )
);

console.log(updated);
0 голосов
/ 23 января 2020

В этой строке for (let j=0; j<=hours_array.length; j++){ вы можете выйти за пределы массива. В вашей ситуации значение array.length равно 10, однако, когда вы пытаетесь получить доступ к элементу с индексом 10, вы получаете неопределенное значение, поскольку ваш последний индекс равен 9. Вы должны либо изменить <= на <, либо уменьшить длину на 1 См. Решение ниже:

for (let i=0; i< hours_array.length; i++){
  for (let j=0; j<hours_array.length; j++){
    if ((hours_array[i]['hour_from'] == hours_array[j]['hour_from']) && (hours_array[i] 
    ['hour_to'] == hours_array[j]['hour_to'])){
      delete hours_array[j];
    }
  }
}

Редактировать: Хорошо, вы понимаете эту проблему, следующая проблема состоит в том, что вы удаляете элемент, если массив все еще находится в цикле. Есть много способов исправить это, но самый простой - создать новый массив и добавить уникальные элементы в этот новый массив. Дайте мне знать, если вам нужна помощь с этим.

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