Динамическая реструктуризация массива объектов, каждый из которых содержит две пары значений свойства - PullRequest
1 голос
/ 28 октября 2019

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

Мне действительно интересно узнать ваше мнение. Я начал с извлечения имен и удаления дубликатов. Оставив меня с массивом, подобным этому: let waiterNames = ['John','Mark','Jess'].

Затем я попытался выполнить двойной цикл for и каким-то образом создать новый массив объектов, но я застрял.

for (entry in waiterInfo) {
    for (waiter in waiterNames) {
        if (entry.waiters == waiter) {
        ???
        }
    }
}

waiterInfo - это то, с чего я начинаю, newInfo - это то, чего я хочу достичь. Мне нужно, чтобы это происходило динамически, потому что данные, взятые из базы данных, непредсказуемы.

let waiterInfo = [{ waiters: 'John', weekdays: 'Monday' },
{ waiters: 'John', weekdays: 'Tuesday' },
{ waiters: 'John', weekdays: 'Wednesday' },
{ waiters: 'Mark', weekdays: 'Monday' },
{ waiters: 'Mark', weekdays: 'Tuesday' },
{ waiters: 'Jess', weekdays: 'Monday' },
{ waiters: 'Jess', weekdays: 'Tuesday' },
{ waiters: 'Jess', weekdays: 'Wednesday' },
{ waiters: 'Jess', weekdays: 'Thursday' }]
let newInfo = [{ waiters: 'John', weekdays: 'Monday, Tuesday, Wednesday'},
{ waiters: 'Mark', weekdays: 'Monday, Tuesday' },
{ waiters: 'Jess', weekdays: 'Monday, Tuesday, Wednesday, Thursday' }]

Ответы [ 3 ]

1 голос
/ 28 октября 2019

Вы можете использовать карту рядом с reduce:

let waiterInfo = [{ waiters: 'John', weekdays: 'Monday' },
  { waiters: 'John', weekdays: 'Tuesday' },
  { waiters: 'John', weekdays: 'Wednesday' },
  { waiters: 'Mark', weekdays: 'Monday' },
  { waiters: 'Mark', weekdays: 'Tuesday' },
  { waiters: 'Jess', weekdays: 'Monday' },
  { waiters: 'Jess', weekdays: 'Tuesday' },
  { waiters: 'Jess', weekdays: 'Wednesday' },
  { waiters: 'Jess', weekdays: 'Thursday' }
]


const map = new Map()

const newInfo = waiterInfo.reduce((a, o) => {
  const i = map.get(o.waiters)
  if(i !== undefined) {
    a[i].weekdays = [a[i].weekdays, o.weekdays].join(', ')
  } else {
    map.set(o.waiters, a.push(o) - 1)
  }
  return a
}, [])

console.log(newInfo)

Временная сложность этого кода равна O ( n ), поскольку мы используем карту.

(Кроме того, это единственный раз, когда я видел полезное возвращаемое значение push)

0 голосов
/ 28 октября 2019

Самый простой способ сделать это - использовать временную Map для отслеживания объектов для официантов, которых вы видели раньше, чтобы вы могли добавить их в список дней.

const waiterMap = new Map();
const newInfo = [];
for (const {waiters, weekdays} of waiterInfo) {
    let entry = waiterMap.get(waiters);
    if (!entry) {
        // New waiter, create the object and put it in the map and result array
        const copy = {waiters, weekdays};
        waiterMap.set(waiters, copy);
        newInfo.push(copy);
    } else {
        // Existing entry, just add to it
        entry.weekdays += `, ${weekdays}`;
    }
}

Пример:

let waiterInfo = [{ waiters: 'John', weekdays: 'Monday' },
{ waiters: 'John', weekdays: 'Tuesday' },
{ waiters: 'John', weekdays: 'Wednesday' },
{ waiters: 'Mark', weekdays: 'Monday' },
{ waiters: 'Mark', weekdays: 'Tuesday' },
{ waiters: 'Jess', weekdays: 'Monday' },
{ waiters: 'Jess', weekdays: 'Tuesday' },
{ waiters: 'Jess', weekdays: 'Wednesday' },
{ waiters: 'Jess', weekdays: 'Thursday' }];

const waiterMap = new Map();
const newInfo = [];
for (const {waiters, weekdays} of waiterInfo) {
    let entry = waiterMap.get(waiters);
    if (!entry) {
        // New waiter, create the object and put it in the map and result array
        const copy = {waiters, weekdays};
        waiterMap.set(waiters, copy);
        newInfo.push(copy);
    } else {
        // Existing entry, just add to it
        entry.weekdays += `, ${weekdays}`;
    }
}

console.log(newInfo);

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

0 голосов
/ 28 октября 2019

Вы можете сделать:

const waiterInfo = [{ waiters: 'John', weekdays: 'Monday' },{ waiters: 'John', weekdays: 'Tuesday' },{ waiters: 'John', weekdays: 'Wednesday' },{ waiters: 'Mark', weekdays: 'Monday' },{ waiters: 'Mark', weekdays: 'Tuesday' },{ waiters: 'Jess', weekdays: 'Monday' },{ waiters: 'Jess', weekdays: 'Tuesday' },{ waiters: 'Jess', weekdays: 'Wednesday' },{ waiters: 'Jess', weekdays: 'Thursday' },]

const result = Object
  .values(
    waiterInfo.reduce((a, { waiters, weekdays }) => {
      a[waiters] = a[waiters] || { waiters, weekdays: [] }
      a[waiters].weekdays.push(weekdays)
      return a
    }, {})
  )
  .map(({ waiters, weekdays }) => ({ waiters, weekdays: weekdays.join(', ') }))

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