Установить одинаковое значение данного свойства для всех объектов в массиве и устранить дубликаты - PullRequest
1 голос
/ 28 апреля 2020

У меня есть этот объект:

{
  "0": {
    "boardingGate": "exit_0",
    "departureTerminal": "1",
    "terminalArea": 0,
    "arrivalGate": "enter_0",
    "arrivalTerminal": "2",
    "terminalArea": 0
  },
  "1": {
    "boardingGate": "exit_1",
    "departureTerminal": "1",
    "terminalArea": 0,
    "arrivalGate": "enter_1",
    "arrivalTerminal": "2",
    "terminalArea": 0
  },
  "2": {
    "boardingGate": "exit_0",
    "departureTerminal": "1",
    "terminalArea": 0,
    "arrivalGate": "enter_0",
    "arrivalTerminal": "3",
    "terminalArea": 0
  },
  "3": {
    "boardingGate": "exit_1",
    "departureTerminal": "2",
    "terminalArea": 0,
    "arrivalGate": "enter_1",
    "arrivalTerminal": "3",
    "terminalArea": 0
  }
}

Мне нужно изменить все значения "boardingGate" на "exit_0" и все значения "ArriGate" на "enter_0". И после изменения мне нужно удалить те, которые дают равную структуру объекта. Конечный результирующий объект, который я ищу, будет следующим:

{
  "0": {
    "boardingGate": "exit_0",
    "departureTerminal": "1",
    "terminalArea": 0,
    "arrivalGate": "enter_0",
    "arrivalTerminal": "2",
    "terminalArea": 0
  },
  "1": {
    "boardingGate": "exit_0",
    "departureTerminal": "1",
    "terminalArea": 0,
    "arrivalGate": "enter_0",
    "arrivalTerminal": "3",
    "terminalArea": 0
  },
  "2": {
    "boardingGate": "exit_0",
    "departureTerminal": "2",
    "terminalArea": 0,
    "arrivalGate": "enter_0",
    "arrivalTerminal": "3",
    "terminalArea": 0
  }
}

Исключая в этом случае один из первых двух, который получит в качестве конечного результата те же данные. Я пытался с forEach получить Object.values ​​(данные), и я не получаю желаемых результатов ... и я не знаю, есть ли более простой способ.

    const tickets = Object.values(data);

    tickets.forEach((next, index, ticket) => {
      const boardingGateKeys: any = Object.keys(next.boardingGate);
      const boardingGateValues: any = Object.values(next.boardingGate);

      boardingGateKeys.forEach((gate, gateIndex) => {
          const arrivalGateKeys: any = Object.keys(gate.outputs);
          const arrivalGateValues: any = Object.values(gate.outputs);
          arrivalGateValues.forEach((output, outputIndex) => {

              });
            }
        });
      });

Большое спасибо за вашу помощь заранее

Ответы [ 2 ]

1 голос
/ 28 апреля 2020

Существуют две проблемы, связанные с вашим кодом:

  • второстепенный (и ваши входные, и ожидаемые объекты недействительны из-за дублирования клавиши terminalArea)
  • и основной один - и ваша попытка, и принятый ответ реализуют алгоритмы времени O (n²) (из-за вложенных циклов), которые могут вызвать огромную потерю производительности ( до 90% медленнее по сравнению с алгоритмом времени O (n) для 1k items ), если ваш ввод будет достаточно большим

Итак, если вы по-прежнему считаете что-то более всеобъемлющим (и, что более важно, быстрым), пожалуйста, проверьте следующий подход:

  • создать карту га sh, содержащую уникальную комбинацию значений входных объектов
  • pu sh переназначенный объект (с унифицированными значениями boardingGate / arrivalGate), если его га sh отсутствует в хэш-карте

Доказательство концепции заключается в следующем:

const src = {"0":{"boardingGate":"exit_0","departureTerminal":"1","departureTerminalArea":0,"arrivalGate":"enter_0","arrivalTerminal":"2","arrivalTerminalArea":0},"1":{"boardingGate":"exit_1","departureTerminal":"1","departureTerminalArea":0,"arrivalGate":"enter_1","arrivalTerminal":"2","arrivalTerminalArea":0},"2":{"boardingGate":"exit_0","departureTerminal":"1","departureTerminalArea":0,"arrivalGate":"enter_0","arrivalTerminal":"3","arrivalTerminalArea":0},"3":{"boardingGate":"exit_1","departureTerminal":"2","departureTerminalArea":0,"arrivalGate":"enter_1","arrivalTerminal":"3","arrivalTerminalArea":0}},

      remapDedupe = input => {
        const hashMap = new Set(),
              result = []
        for(idx in input){
          const {boardingGate, arrivalGate, ...rest} = input[idx],
                hash = Object.values(rest).join('|')
          if(hashMap.has(hash)) continue               
          result.push({
            boardingGate: 'exit_0', 
            arrivalGate: 'enter_0', 
            ...rest
          })
          hashMap.add(hash)
        }
        return {...result}
      },
      
      result = remapDedupe(src)
        
console.log(result)
.as-console-wrapper{min-height:100%;}
1 голос
/ 28 апреля 2020

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

Наконец, создайте объект из массива.

var data = { 0: { boardingGate: "exit_0", departureTerminal: "1", terminalArea: 0, arrivalGate: "enter_0", arrivalTerminal: "2" }, 1: { boardingGate: "exit_1", departureTerminal: "1", terminalArea: 0, arrivalGate: "enter_1", arrivalTerminal: "2" }, 2: { boardingGate: "exit_0", departureTerminal: "1", terminalArea: 0, arrivalGate: "enter_0", arrivalTerminal: "3" }, 3: { boardingGate: "exit_1", departureTerminal: "2", terminalArea: 0, arrivalGate: "enter_1", arrivalTerminal: "3" } },
    result = Object.assign({}, Object
        .values(data)
        .reduce((r, { boardingGate, arrivalGate, ...o }) => {
            const entries = Object.entries(o);
            if (!r.some(q => entries.every(([k, v]) => q[k] === v))) {
                r.push({ boardingGate: "exit_0", arrivalGate: "enter_0", ...o });
            }
            return r;
        }, [])
    );

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