Оптимальный способ прохождения большого набора данных - PullRequest
3 голосов
/ 27 июня 2019

У меня большой набор значений в виде JSON.Ниже приведен небольшой снимок этого объекта JSON.

 {
     "response": [
     {
         "data": [
         {
             "value": 1,
             "minute": "2019-06-10 11:51",
             "action": "firstApp",
         },
         {
             "value": 10,
             "minute": "2019-06-10 11:51",
             "action": "secondApp",
         },
         {
             "value": 100,
             "minute": "2019-06-10 11:51",
             "action": "thirdApp",
         },
         {
             "value": 10,
             "minute": "2019-06-10 11:52",
             "action": "firstApp",
         },
         {
             "value": 20,
             "minute": "2019-06-10 11:52",
             "action": "secondApp",
         },
         {
             "value": 115,
             "minute": "2019-06-10 11:52",
             "action": "thirdApp",
         }, ]
     }]
 }

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

[
   {
       "timestamp" : "2019-06-10 11:51",
       "firstApp" : {
           "value" : 1,
       }, 
       "secondApp": {
           "value":10,
       },
       "thirdApp": {
           "value" : 100,
       }
   },
   {
       "timestamp" : "2019-06-10 11:52",
       "firstApp" : {
           "value" : 10
       }, 
       "secondApp": {
           "value":20,
       },
       "thirdApp": {
           "value" : 115,
       }
   }
]

Я написал следующий код как таковой, но это занимает много времени ( около 10-12 секунд ) (что вполне ожидаемо). Пожалуйста, обратитесь к этой CodeSandbox (https://codesandbox.io/s/objective-bartik-0r30j?autoresize=1&expanddevtools=1&fontsize=14&hidenavigation=1&module=%2Fsrc%2Findex.js), чтобы увидеть код в действии.

Проблема, с которой я сталкиваюсьявляется то, что это занимает много времени (и это справедливо), чтобы дать

  1. Набор данных огромен
  2. Мой код плохой - так как здесь и там слишком много циклов

У меня нет контроля над 1, но я определенно контролирую над 2. Не могли бы вы дать мне несколько идей относительно того, как я могу решить эту проблему?

Обновление Вот скриншот с вкладки производительности [! [Введите описание изображения здесь] [1]] [1]

Спасибо

let data = {
  response: [
    {
      data: [
        {
          value: 1,
          minute: "2019-06-10 11:51",
          action: "firstApp"
        },
        {
          value: 10,
          minute: "2019-06-10 11:51",
          action: "secondApp"
        },
        {
          value: 100,
          minute: "2019-06-10 11:51",
          action: "thirdApp"
        },
        {
          value: 10,
          minute: "2019-06-10 11:52",
          action: "firstApp"
        },
        {
          value: 20,
          minute: "2019-06-10 11:52",
          action: "secondApp"
        },
        {
          value: 115,
          minute: "2019-06-10 11:52",
          action: "thirdApp"
        }
      ]
    }
  ]
};

function massageData(data) {
  let historyData = [];
  let uniqueTimeStamps = [];
  let event = {
    timestamp: "",
    firstApp: {
      value: 0
    },
    secondApp: {
      value: 0
    },
    thirdApp: {
      value: 0
    }
  };

  for (var i = 0; i < data.length; i++) {
    let item = data[i];

    if (item.minute) {
      if (!uniqueTimeStamps.includes(item.minute)) {
        let timestamp = item.minute;
        console.log("--------------------");
        console.log(timestamp);
        event.timestamp = timestamp;
        event.firstApp.value = getDataValue(data, timestamp, "firstApp");
        event.secondApp.value = getDataValue(data, timestamp, "secondApp");
        event.thirdApp.value = getDataValue(data, timestamp, "thirdApp");
        console.log(event);
        historyData.push(event);
        uniqueTimeStamps.push(item.minute);
      }
    }
  }

  return historyData;
}

function getDataValue(data, timestamp, action) {
  for (var i = 0, len = data.length; i < len; i++) {
    let item = data[i];
    console.log(item);
    if (item["minute"] === timestamp && item["action"] === action) {
      return parseInt(item["value"]);
    }
  }
}

let workData = data.response[0].data;
let formattedData = massageData(workData);
console.log(formattedData);

Ответы [ 2 ]

2 голосов
/ 27 июня 2019

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

function massageData(data) {
    var historyData = [],
        hash = Object.create(null),
        i, item;

    for (i = 0; i < data.length; i++) {
        item = data[i];
        if (!hash[item.minute]) {
            historyData.push(hash[item.minute] = { timestamp: item.minute, firstApp: { value: 0 }, secondApp: { value: 0 }, thirdApp: { value: 0 } });
        }
        hash[item.minute][item.action].value = item.value;
    }
    return historyData;
}

var data = { response: [{ data: [{ value: 1, minute: "2019-06-10 11:51", action: "firstApp" }, { value: 10, minute: "2019-06-10 11:51", action: "secondApp" }, { value: 100, minute: "2019-06-10 11:51", action: "thirdApp" }, { value: 10, minute: "2019-06-10 11:52", action: "firstApp" }, { value: 20, minute: "2019-06-10 11:52", action: "secondApp" }, { value: 115, minute: "2019-06-10 11:52", action: "thirdApp" }] }] },
    workData = data.response[0].data,
    formattedData = massageData(workData);

console.log(formattedData);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 27 июня 2019

Другой аналогичный подход, включающий использование объекта в качестве хеш-таблицы, приведен ниже.Это должно быть немного легче следовать:

function massageData (data) {
  const events = [];
  const timestamps = {};

  for (let i = 0; i < data.length; i++) {
    const { action, minute, ...item } = data[i];

    if (!(minute in timestamps)) {
      const event = { timestamp: minute };

      events.push(event);
      timestamps[minute] = event;
    }

    timestamps[minute][action] = item;
  }

  return events;
}

const data = [{ value: 1, minute: "2019-06-10 11:51", action: "firstApp" }, { value: 10, minute: "2019-06-10 11:51", action: "secondApp" }, { value: 100, minute: "2019-06-10 11:51", action: "thirdApp" }, { value: 10, minute: "2019-06-10 11:52", action: "firstApp" }, { value: 20, minute: "2019-06-10 11:52", action: "secondApp" }, { value: 115, minute: "2019-06-10 11:52", action: "thirdApp" }];

console.log(massageData(data));

Это скопирует все свойства в каждом элементе, кроме minute и action, в объект в каждом event как вычисляемое свойство [action].Если value действительно единственное другое свойство, которое существует в каждом item, то код можно упростить:

function massageData (data) {
  const events = [];
  const timestamps = {};

  for (let i = 0; i < data.length; i++) {
    const { action, minute, value } = data[i];

    if (!(minute in timestamps)) {
      const event = { timestamp: minute };

      events.push(event);
      timestamps[minute] = event;
    }

    timestamps[minute][action] = { value };
  }

  return events;
}

const data = [{ value: 1, minute: "2019-06-10 11:51", action: "firstApp" }, { value: 10, minute: "2019-06-10 11:51", action: "secondApp" }, { value: 100, minute: "2019-06-10 11:51", action: "thirdApp" }, { value: 10, minute: "2019-06-10 11:52", action: "firstApp" }, { value: 20, minute: "2019-06-10 11:52", action: "secondApp" }, { value: 115, minute: "2019-06-10 11:52", action: "thirdApp" }];

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