Как перебрать массив массивов, чтобы отфильтровать или отклонить повторяющиеся записи?

Я хочу перебрать этот двумерный массив. Массивы с несколькими объектами имеют несколько записей в одном и том же месяце (в примере ниже — январь). Я хочу отфильтровать (отклонить) повторяющиеся записи и вернуть измененный массив.

Я пробовал разные решения здесь, на SO, но пока не смог; Я буду признателен за любой вклад!

[[
  { "id":"9","bookingReason":"Netto Neu Eigen","bookingDate":"2021-01-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"10","bookingReason":"Netto Neu Eigen","bookingDate":"2021-01-23","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"9","bookingReason":"Netto Neu Eigen","bookingDate":"2021-01-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"10","bookingReason":"Netto Neu Eigen","bookingDate":"2021-01-23","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"29","bookingReason":"Netto Neu Eigen","bookingDate":"2022-01-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"30","bookingReason":"Netto Neu Eigen","bookingDate":"2022-01-23","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"29","bookingReason":"Netto Neu Eigen","bookingDate":"2022-01-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"30","bookingReason":"Netto Neu Eigen","bookingDate":"2022-01-23","bookingType":"Gutschrift","bookingPoints":"100" }
]]

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

Изменить ответ Петру Селигеру: Результат должен сохранить двумерную структуру.

[
  [{
    "id": "1",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-09-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "2",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-08-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "3",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-07-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "4",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-06-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "5",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-05-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "6",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-04-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "7",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-03-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }, {
    "id": "12",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-03-24",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "8",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-02-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }, {
    "id": "11",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-02-23",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "9",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-01-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }, {
    "id": "10",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-01-23",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "9",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-01-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }, {
    "id": "10",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-01-23",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "8",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-02-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }, {
    "id": "11",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-02-23",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "7",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-03-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }, {
    "id": "12",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2021-03-24",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "21",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-09-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "22",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-08-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "23",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-07-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "24",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-06-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "25",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-05-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "26",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-04-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "27",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-03-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }, {
    "id": "32",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-03-24",
    "bookingType": "Gutschrift",
    "bookingPoints": "200"
  }], [{
    "id": "28",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-02-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }, {
    "id": "31",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-02-23",
    "bookingType": "Gutschrift",
    "bookingPoints": "400"
  }], [{
    "id": "29",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-01-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }, {
    "id": "30",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-01-23",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "29",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-01-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }, {
    "id": "30",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-01-23",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }], [{
    "id": "28",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-02-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }, {
    "id": "31",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-02-23",
    "bookingType": "Gutschrift",
    "bookingPoints": "400"
  }], [{
    "id": "27",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-03-22",
    "bookingType": "Gutschrift",
    "bookingPoints": "100"
  }, {
    "id": "32",
    "bookingReason": "Netto Neu Eigen",
    "bookingDate": "2022-03-24",
    "bookingType": "Gutschrift",
    "bookingPoints": "200"
  }]
]

Какое тестирование минимум необходимо провести, чтобы установить, что две записи в основном массиве являются дубликатами? Вы также можете уточнить, должен ли алгоритм фильтрации выполнять предварительную проверку достоверности того, что он пропускает. (Пожалуйста, отредактируйте вопрос, чтобы добавить дополнительную информацию, а не пытаться добавить ее в качестве комментария).

traktor 10.05.2022 13:38

@traktor Хорошо, я сделал, надеюсь, это поможет

AlexJanow 10.05.2022 13:56

@AlexJanow ... пожалуйста, предоставьте структуру данных как синтаксически правильный / действительный литерал объекта, сокращенный до самых необходимых данных (а не как неполный / свернутый копи-вставить-дамп из консоли). Прямо сейчас можно только догадываться о правильной структуре того, что OP называет "массив массивов".

Peter Seliger 10.05.2022 14:04

@AlexJanow ... Отсутствует еще одна важная информация. Должен ли результат сохранять двумерную структуру массива? Или целевая структура должна быть плоским (сжатым) массивом уникальных (с точки зрения OP по уникальному id значению) элементов?

Peter Seliger 10.05.2022 14:11

@Peter Seliger, отредактировано, надеюсь, вы это имели в виду.

AlexJanow 10.05.2022 14:36

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

Nina Scholz 10.05.2022 16:23
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
6
64
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Что на самом деле означает ОП с ...

"I want to filter out the double entries and want to return the filtered array."

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

"So if the filter finds for example the same id a second time, the whole duplicate array should get removed."

"Edit answer to Peter Seliger: The result should keep the 2-dimensional structure."

Таким образом, нужно придумать рекурсивно работающий подход отклонятьing.

Предоставленная реализация использует поиск определенного значения пользовательского ключа (имени свойства). Если значение еще не существует, итерация продолжается, но значение присваивается поиску. Любой элемент массива, который имеет такое же, уже назначенное значение, получает spliceed из массива (что является задачей мутации) и помещается в локальный массив rejected. Возвращаемое значение функции представляет собой объект, который содержит два массива... mutated со ссылкой на переданную и обработанную/измененную структуру данных и rejected, который представляет собой плоский список элементов, которые были отклонены из предоставленной структуры данных.

function rejecItemsOfSameKeyAndValueRecursively(
  arr = [], key = '', lookup = new Map,
) {
  const rejected = [];

  for (let idx = 0; idx < arr.length; idx++) {
    const item = arr[idx];

    if (Array.isArray(item)) {

      // recursion in order to handle nested array structures.
      rejected
        .push(
          ...rejecItemsOfSameKeyAndValueRecursively(item, key, lookup).rejected
        );

      // ... and in case one wants to also get rid
      //     of the now possibly empty array item ...
      if (item.length === 0) {
        // remove empty array item.
        arr.splice(idx, 1);
        // re/adjust the proceeding index value.
        --idx; 
      }

    } else if (!!item && typeof item === 'object') {
      const value = item[key];

      if (lookup.has(value)) {

        rejected
          .push(
            // remove duplicate item from array.
            arr.splice(idx, 1)
          );

        --idx; // re/adjust the proceeding index value.

      } else {
        lookup.set(value, value);
      }
    }
  }
  return { mutated: arr, rejected };
}

const sampleData = [[
  { "id":"1","bookingReason":"Netto Neu Eigen","bookingDate":"2021-09-22","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"2","bookingReason":"Netto Neu Eigen","bookingDate":"2021-08-22","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"3","bookingReason":"Netto Neu Eigen","bookingDate":"2021-07-22","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"4","bookingReason":"Netto Neu Eigen","bookingDate":"2021-06-22","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"5","bookingReason":"Netto Neu Eigen","bookingDate":"2021-05-22","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"6","bookingReason":"Netto Neu Eigen","bookingDate":"2021-04-22","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"7","bookingReason":"Netto Neu Eigen","bookingDate":"2021-03-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"12","bookingReason":"Netto Neu Eigen","bookingDate":"2021-03-24","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"8","bookingReason":"Netto Neu Eigen","bookingDate":"2021-02-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"11","bookingReason":"Netto Neu Eigen","bookingDate":"2021-02-23","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"9","bookingReason":"Netto Neu Eigen","bookingDate":"2021-01-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"10","bookingReason":"Netto Neu Eigen","bookingDate":"2021-01-23","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"9","bookingReason":"Netto Neu Eigen","bookingDate":"2021-01-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"10","bookingReason":"Netto Neu Eigen","bookingDate":"2021-01-23","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"8","bookingReason":"Netto Neu Eigen","bookingDate":"2021-02-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"11","bookingReason":"Netto Neu Eigen","bookingDate":"2021-02-23","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"7","bookingReason":"Netto Neu Eigen","bookingDate":"2021-03-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"12","bookingReason":"Netto Neu Eigen","bookingDate":"2021-03-24","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"21","bookingReason":"Netto Neu Eigen","bookingDate":"2022-09-22","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"22","bookingReason":"Netto Neu Eigen","bookingDate":"2022-08-22","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"23","bookingReason":"Netto Neu Eigen","bookingDate":"2022-07-22","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"24","bookingReason":"Netto Neu Eigen","bookingDate":"2022-06-22","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"25","bookingReason":"Netto Neu Eigen","bookingDate":"2022-05-22","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"26","bookingReason":"Netto Neu Eigen","bookingDate":"2022-04-22","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"27","bookingReason":"Netto Neu Eigen","bookingDate":"2022-03-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"32","bookingReason":"Netto Neu Eigen","bookingDate":"2022-03-24","bookingType":"Gutschrift","bookingPoints":"200" }
], [
  { "id":"28","bookingReason":"Netto Neu Eigen","bookingDate":"2022-02-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"31","bookingReason":"Netto Neu Eigen","bookingDate":"2022-02-23","bookingType":"Gutschrift","bookingPoints":"400" }
], [
  { "id":"29","bookingReason":"Netto Neu Eigen","bookingDate":"2022-01-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"30","bookingReason":"Netto Neu Eigen","bookingDate":"2022-01-23","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"29","bookingReason":"Netto Neu Eigen","bookingDate":"2022-01-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"30","bookingReason":"Netto Neu Eigen","bookingDate":"2022-01-23","bookingType":"Gutschrift","bookingPoints":"100" }
], [
  { "id":"28","bookingReason":"Netto Neu Eigen","bookingDate":"2022-02-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"31","bookingReason":"Netto Neu Eigen","bookingDate":"2022-02-23","bookingType":"Gutschrift","bookingPoints":"400" }
], [
  { "id":"27","bookingReason":"Netto Neu Eigen","bookingDate":"2022-03-22","bookingType":"Gutschrift","bookingPoints":"100" },
  { "id":"32","bookingReason":"Netto Neu Eigen","bookingDate":"2022-03-24","bookingType":"Gutschrift","bookingPoints":"200" }
]];

const cloneDataStructure = (typeof structuredClone === 'function')
  ? structuredClone
  : value => JSON.parse(JSON.stringify(value));


const data = cloneDataStructure(sampleData);
const { mutated, rejected } = rejecItemsOfSameKeyAndValueRecursively(data, 'id');

console.info(
  '... mutated/rejected by `id` ... ',
);
console.info(
  '(mutated === data) ?..',
  (mutated === data),
);
console.info(
  { mutated, rejected },
);


const data_2 = cloneDataStructure(sampleData);
const { mutated: mutated_2, rejected: rejected_2 } =
  rejecItemsOfSameKeyAndValueRecursively(cloneDataStructure(data_2), 'bookingPoints');

console.info(
  '... mutated/rejected by `bookingPoints` ... ',
);
console.info(
  '(mutated_2 === data_2) ?..',
  (mutated_2 === data_2),
);
console.info(
  { mutated_2, rejected_2 },
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

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

Peter Seliger 10.05.2022 19:22

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

const dedupe = (
  data, found = new Set(), result,
  test = (x) => ((result = ! found .has (x .id)), (found .add (x .id)), result)
) => data .map ((group) => group .filter (test)) .filter (x => x .length > 0)


const data = [[{id: "1", bookingReason: "Netto Neu Eigen", bookingDate: "2021-09-22", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "2", bookingReason: "Netto Neu Eigen", bookingDate: "2021-08-22", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "3", bookingReason: "Netto Neu Eigen", bookingDate: "2021-07-22", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "4", bookingReason: "Netto Neu Eigen", bookingDate: "2021-06-22", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "5", bookingReason: "Netto Neu Eigen", bookingDate: "2021-05-22", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "6", bookingReason: "Netto Neu Eigen", bookingDate: "2021-04-22", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "7", bookingReason: "Netto Neu Eigen", bookingDate: "2021-03-22", bookingType: "Gutschrift", bookingPoints: "100"}, {id: "12", bookingReason: "Netto Neu Eigen", bookingDate: "2021-03-24", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "8", bookingReason: "Netto Neu Eigen", bookingDate: "2021-02-22", bookingType: "Gutschrift", bookingPoints: "100"}, {id: "11", bookingReason: "Netto Neu Eigen", bookingDate: "2021-02-23", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "9", bookingReason: "Netto Neu Eigen", bookingDate: "2021-01-22", bookingType: "Gutschrift", bookingPoints: "100"}, {id: "10", bookingReason: "Netto Neu Eigen", bookingDate: "2021-01-23", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "9", bookingReason: "Netto Neu Eigen", bookingDate: "2021-01-22", bookingType: "Gutschrift", bookingPoints: "100"}, {id: "10", bookingReason: "Netto Neu Eigen", bookingDate: "2021-01-23", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "8", bookingReason: "Netto Neu Eigen", bookingDate: "2021-02-22", bookingType: "Gutschrift", bookingPoints: "100"}, {id: "11", bookingReason: "Netto Neu Eigen", bookingDate: "2021-02-23", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "7", bookingReason: "Netto Neu Eigen", bookingDate: "2021-03-22", bookingType: "Gutschrift", bookingPoints: "100"}, {id: "12", bookingReason: "Netto Neu Eigen", bookingDate: "2021-03-24", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "21", bookingReason: "Netto Neu Eigen", bookingDate: "2022-09-22", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "22", bookingReason: "Netto Neu Eigen", bookingDate: "2022-08-22", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "23", bookingReason: "Netto Neu Eigen", bookingDate: "2022-07-22", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "24", bookingReason: "Netto Neu Eigen", bookingDate: "2022-06-22", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "25", bookingReason: "Netto Neu Eigen", bookingDate: "2022-05-22", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "26", bookingReason: "Netto Neu Eigen", bookingDate: "2022-04-22", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "27", bookingReason: "Netto Neu Eigen", bookingDate: "2022-03-22", bookingType: "Gutschrift", bookingPoints: "100"}, {id: "32", bookingReason: "Netto Neu Eigen", bookingDate: "2022-03-24", bookingType: "Gutschrift", bookingPoints: "200"}], [{id: "28", bookingReason: "Netto Neu Eigen", bookingDate: "2022-02-22", bookingType: "Gutschrift", bookingPoints: "100"}, {id: "31", bookingReason: "Netto Neu Eigen", bookingDate: "2022-02-23", bookingType: "Gutschrift", bookingPoints: "400"}], [{id: "29", bookingReason: "Netto Neu Eigen", bookingDate: "2022-01-22", bookingType: "Gutschrift", bookingPoints: "100"}, {id: "30", bookingReason: "Netto Neu Eigen", bookingDate: "2022-01-23", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "29", bookingReason: "Netto Neu Eigen", bookingDate: "2022-01-22", bookingType: "Gutschrift", bookingPoints: "100"}, {id: "30", bookingReason: "Netto Neu Eigen", bookingDate: "2022-01-23", bookingType: "Gutschrift", bookingPoints: "100"}], [{id: "28", bookingReason: "Netto Neu Eigen", bookingDate: "2022-02-22", bookingType: "Gutschrift", bookingPoints: "100"}, {id: "31", bookingReason: "Netto Neu Eigen", bookingDate: "2022-02-23", bookingType: "Gutschrift", bookingPoints: "400"}], [{id: "27", bookingReason: "Netto Neu Eigen", bookingDate: "2022-03-22", bookingType: "Gutschrift", bookingPoints: "100"}, {id: "32", bookingReason: "Netto Neu Eigen", bookingDate: "2022-03-24", bookingType: "Gutschrift", bookingPoints: "200"}]]

console .log (dedupe (data))
.as-console-wrapper {max-height: 100% !important; top: 0}

Мы пишем то, чего я обычно стараюсь избегать: функцию с состоянием, закрывающую изменяемый набор id, которые мы видели до сих пор. Эта функция используется в качестве обратного вызова для filter вызовов вложенных массивов. Я стараюсь избегать функций с состоянием, но альтернатива казалась сложной — вложенные складки, и это работает хорошо.

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

Эта версия синтаксически плотная. Следующий вариант может быть более привлекательным для некоторых людей:

const dedupe = (data) => {
  const found = new Set()
  const test = (x) => {
    const result = ! found .has (x .id)
    found .add (x .id)
    return result
  }
  return data .map ((group) => group .filter (test)) 
              .filter (x => x .length > 0)
}

Они делают то же самое.

Другие вопросы по теме