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

#javascript #arrays #ecmascript-6

Вопрос:

Я использую [...new Set] для создания нового массива уникальных элементов, проблема, с которой я сталкиваюсь, заключается в том, что конечной целью является создание нового массива объектов, которые должны быть уникальными (или, по крайней мере, уникальными в соответствии с первым свойством).

Некоторые примеры данных:

 const props = {};
props.gridData = [
    {
        "id": 198,
        "dateReceived": "2020-12-29T10:10:45.513",
        "title": "Contracts Submitted",
        "subject": "Contract(s) for xxx Ltd submitted.",
        "readUnread": false,
        "userId": 13,
        "emailAddress": "autotestsmecustomer@company.com",
        "organisation": 43,
        "callToAction": "string",
        "json": "<h1>Your latest statement is here</h1>",
        "name": "Name"
    },
    {
        "id": 337,
        "dateReceived": "2021-04-09T11:41:03.033",
        "title": "Your latest invoice is now ready to view",
        "subject": "Your latest invoice is here (Account ID XXXXXX)",
        "readUnread": true,
        "userId": 13,
        "emailAddress": "autotestsmecustomer@company.com",
        "organisation": 43,
        "callToAction": null,
        "json": "<h1>Your latest invoice is here</h1>",
        "name": "Ebill"
    },
    {
        "id": 343,
        "dateReceived": "2021-04-09T11:41:03.047",
        "title": "Meter read reminder",
        "subject": "6,Unit 1, Somewhere, Somewhere Else, AB1 1YZ",
        "readUnread": true,
        "userId": 13,
        "emailAddress": "autotestsmecustomer@company.com",
        "organisation": 43,
        "callToAction": null,
        "json": "<h1>Your latest statement is here</h1>",
        "name": "MeterReadReminder"
    },
    {
        "id": 387,
        "dateReceived": "2021-05-07T07:26:40.653",
        "title": "Your latest invoice is now ready to view",
        "subject": "Your latest invoice is here (Account ID XXXXXX)",
        "readUnread": false,
        "userId": 13,
        "emailAddress": "autotestsmecustomer@company.com",
        "organisation": 43,
        "callToAction": "NULL",
        "json": "<h1>Your latest invoice is here</h1>",
        "name": "Ebill"
    },
    ...
]
 

Вот мой текущий JS:

 const filteredItems = () => [...new Set(props.gridData.map(item =>
    item.name
))];
 

Это создаст новый массив уникальных элементов. Цель состоит в том, чтобы отфильтрованные элементы выглядели так:

 const filteredItems = [
  { value: 'MeterReadReminder', display: 'Meter Read Reminder' },
  { value: 'Ebill', display: 'Your latest invoice is now ready to view' },
  ...
];
 

Очевидно, что значение и отображение будут считываться из функции карты и т. 'value': item.name Д.

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

(Я использую React и TS, но jsfiddle-это чистый js).

JSFIDDLE

Ответ №1:

Вы можете использовать Array.find , чтобы найти 1-й элемент из массива.

 let gridData = [{ "title": "Contracts Submitted", "name": "Name" }, { "title": "Your latest invoice is now ready to view", "name": "Ebill" }, { "title": "Meter read reminder", "name": "MeterReadReminder" }, { "title": "Your latest invoice is now ready to view", "name": "Ebill" },];

const filteredItems = [...new Set(gridData.map(item => item.name))];

let results = filteredItems.map((value) => ({
    value,
    display: gridData.find(item => item.name == value)["title"]
}))

console.log(results); 

Вы можете значительно оптимизировать производительность с помощью поиска, что-то вроде этого:

 let gridData = [{ "title": "Contracts Submitted", "name": "Name" }, { "title": "Your latest invoice is now ready to view", "name": "Ebill" }, { "title": "Meter read reminder", "name": "MeterReadReminder" }, { "title": "Your latest invoice is now ready to view", "name": "Ebill" },],
    result = [], set = new Set;

for (const { name, title } of gridData) {
    if (set.has(name)) continue;
    result.push({ value: name, display: title });
    set.add(name)
}
console.log(result); 

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

1. Спасибо! Они оба выглядят очень многообещающе, я скоро это проверю. Ta

2. Да, оба работают, пытаясь решить, какой из них я предпочитаю, я думаю, вариант 1, как я его лучше понимаю. Большое спасибо за ваше время (я бы все равно хотел, чтобы это было возвращено из одной константы или функции, но я не знаю, возможно ли это).

3. @lharby, используйте 2-й, который в 100 раз быстрее, чем 1-й подход, если gridData он большой, это будет более чем в 1000 раз быстрее!