Фильтр массива объектов на основе повторяющихся значений

#javascript #arrays

Вопрос:

Я пытаюсь заполнить массив объектов в пользовательском интерфейсе, который имеет повторяющиеся свойства title with teacher и students value.

Пожалуйста, найдите исходные данные —

 const data = [
{
    id: "1",
    title: "Principle",
    name: "John Doe",
    children: [
    {
        id: "random id",
        title: "Teacher",
        name: "Clark Kent",
    },
    {
        id: "random id",
        title: "Teacher",
        name: "Bruce Wayne",
        children: [
        {
            id: "random id",
            title: "Student",
            name: "Jason Todd",
        },
        {
            id: "random id",
            title: "Student",
            name: "Dick Grayson",
        },
        {
            id: "random id",
            title: "Student",
            name: "Tim Drake",
        },
        {
            id: "random id",
            title: "Student",
            name: "Jason Todd",
        },
        {
            id: "random id",
            title: "Student",
            name: "Jason Todd",
        },
        {
            id: "random id",
            title: "Student",
            name: "Jason Todd",
        },
        {
            id: "random id",
            title: "Student",
            name: "Jason Todd",
        },
        ],
    },
    {
        id: "random id",
        title: "Teacher",
        name: "Clark Kent",
    },
    {
        id: "random id",
        title: "Teacher",
        name: "Barry Allen",
    },
    {
        id: "random id",
        title: "Teacher",
        name: "Clark Kent",
    },
    {
        id: "random id",
        title: "Teacher",
        name: "Clark Kent",
    },
    {
        id: "random id",
        title: "Teacher",
        name: "Clark Kent",
    },
    ],
},
];
 

который содержит principal , teacher , и students . Например, если имя учителя повторяется и встречается, например , 5 раз в данных для Clark Kent , то я хочу ограничить данные, чтобы показать 3 записи и добавить один объект, чтобы указать, что есть больше записей с этим именем. как показано ниже —

   {
    id: "random id",
    title: "Teacher",
    name: "Clark Kent",
    more: true,
    remaining: 2,
  },
 

В конце концов, мои данные могут выглядеть как приведенный ниже формат для заполнения в пользовательском интерфейсе —

 const data = [
{
    id: "1",
    title: "Principle",
    name: "John Doe",
    children: [
    {
        id: "random id",
        title: "Teacher",
        name: "Clark Kent",
    },
    {
        id: "random id",
        title: "Teacher",
        name: "Bruce Wayne",
        children: [
        {
            id: "random id",
            title: "Student",
            name: "Jason Todd",
        },
        {
            id: "random id",
            title: "Student",
            name: "Dick Grayson",
        },
        {
            id: "random id",
            title: "Student",
            name: "Tim Drake",
        },
        {
            id: "random id",
            title: "Student",
            name: "Jason Todd",
        },
        {
            id: "random id",
            title: "Student",
            name: "Jason Todd",
        },
        {
            id: "random id",
            title: "Student",
            name: "Jason Todd",
            more: true,
            remaining: 2,
        },
        ],
    },
    {
        id: "random id",
        title: "Teacher",
        name: "Clark Kent",
    },
    {
        id: "random id",
        title: "Teacher",
        name: "Barry Allen",
    },
    {
        id: "random id",
        title: "Teacher",
        name: "Clark Kent",
    },
    {
        id: "random id",
        title: "Teacher",
        name: "Clark Kent",
        more: true,
        remaining: 2,
    },
    ],
},
];
 

Пожалуйста, помогите.

Комментарии:

1. Разве оставшаяся собственность Кларка Кента не должна быть 1?

2. ПРИВЕТ @PaoloTormon, объект, который more добавляется, будет объединен в пользовательском интерфейсе как » 2 больше Кларка Кента » с ${remaining} ${name}, Click to view more пользовательским интерфейсом, поэтому мы можем сохранить Кларка Кента как 2

Ответ №1:

Некоторые предположения:

  1. id в разделе «еще» объект просто копируется от первого лица.
  2. Никакой children области не ожидается у чрезмерных людей.
 const data = [
  {
    id: '1',
    title: 'Principle',
    name: 'John Doe',
    children: [
      {
        id: 'random id',
        title: 'Teacher',
        name: 'Clark Kent',
      },
      {
        id: 'random id',
        title: 'Teacher',
        name: 'Bruce Wayne',
        children: [
          {
            id: 'random id',
            title: 'Student',
            name: 'Jason Todd',
          },
          {
            id: 'random id',
            title: 'Student',
            name: 'Dick Grayson',
          },
          {
            id: 'random id',
            title: 'Student',
            name: 'Tim Drake',
          },
          {
            id: 'random id',
            title: 'Student',
            name: 'Jason Todd',
          },
          {
            id: 'random id',
            title: 'Student',
            name: 'Jason Todd',
          },
          {
            id: 'random id',
            title: 'Student',
            name: 'Jason Todd',
          },
          {
            id: 'random id',
            title: 'Student',
            name: 'Jason Todd',
          },
        ],
      },
      {
        id: 'random id',
        title: 'Teacher',
        name: 'Clark Kent',
      },
      {
        id: 'random id',
        title: 'Teacher',
        name: 'Barry Allen',
      },
      {
        id: 'random id',
        title: 'Teacher',
        name: 'Clark Kent',
      },
      {
        id: 'random id',
        title: 'Teacher',
        name: 'Clark Kent',
      },
      {
        id: 'random id',
        title: 'Teacher',
        name: 'Clark Kent',
      },
    ],
  },
];

const result = reduceRepetitions(data, 'name', 3);
console.log(JSON.stringify(result, null, '  '));

function reduceRepetitions(array, checkKey, maxRepetitions) {
  const reduced = [];

  const counter = {};

  for (const person of array) {
    const checkValue = person[checkKey];
    counter[checkValue] ??= { count: 0, moreObject: null };
    counter[checkValue].count  ;
    if (counter[checkValue].count <= maxRepetitions) {
      reduced.push({
        ...person,
        ...person.children ?
          { children: reduceRepetitions(person.children, checkKey, maxRepetitions) } :
          {},
      });
    } else if (!counter[checkValue].moreObject) {
      counter[checkValue].moreObject = { ...person, more: true, remaining: 1 };
      reduced.push(counter[checkValue].moreObject);
    } else {
      counter[checkValue].moreObject.remaining  ;
    }
  }

  return reduced;
}