Каков самый быстрый способ глубокого сравнения двух объектов в javascript / nodejs

#javascript #node.js #json

#javascript #node.js #json

Вопрос:

У меня есть два больших объекта в JSON, я загружаю их с помощью fs, анализирую и меняю на MAP

 let dataPin = fs.readFileSync('pin.json');
let dataTotal = fs.readFileSync('total.json');
let t = JSON.parse(dataTotal);
let p = JSON.parse(dataPin);

let Map1 = new Map()
 for (let entry in t) {
     let key = t[entry]
     Map1.set(key, entry)
 }

 let Map2 = new Map()
  for (let entry in p) {
      let key = p[entry]
      Map2.set(key, entry)
  }

  

Чем использование двух foreach. Я должен сравнить все значения друг с другом и проверить, содержится ли в них какое-либо из них.

 Map1.forEach((i1,p)=>{
  Map2.forEach((i2,t)=>{

    if(t.eventStart==p.timestamp amp;amp; ( p.home.includes(t.home) || t.home.includes(p.home) || p.away.includes(t.away) || t.away.includes(p.away) )){
   // than do some stuff
 }
 });
});

  

Скрипту требуется около 10 секунд для выполнения с двумя 4 МБ json, я хочу найти более быстрый способ, есть ли он? Я использую node.js

Пример json

 [
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"spread",
      "odd":1.5424,
      "selection":"away",
      "points":1.5,
      "period":0,
      "payout":"1.497"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"spread",
      "odd":2.8437,
      "selection":"home",
      "points":-1.5,
      "period":0,
      "payout":"2.760"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"spread",
      "odd":1.6755,
      "selection":"away",
      "points":1.25,
      "period":0,
      "payout":"1.628"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"spread",
      "odd":2.4803,
      "selection":"home",
      "points":-1.25,
      "period":0,
      "payout":"2.410"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"spread",
      "odd":1.9,
      "selection":"away",
      "points":1,
      "period":0,
      "payout":"1.854"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"spread",
      "odd":2.1111,
      "selection":"home",
      "points":-1,
      "period":0,
      "payout":"2.060"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"spread",
      "odd":2.2309,
      "selection":"away",
      "points":0.75,
      "period":0,
      "payout":"2.170"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"spread",
      "odd":1.8124,
      "selection":"home",
      "points":-0.75,
      "period":0,
      "payout":"1.763"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"spread",
      "odd":2.5611,
      "selection":"away",
      "points":0.5,
      "period":0,
      "payout":"2.490"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"spread",
      "odd":1.6406,
      "selection":"home",
      "points":-0.5,
      "period":0,
      "payout":"1.595"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":1.2069,
      "selection":"under",
      "points":4.5,
      "period":0,
      "payout":"1.165"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":5.8326,
      "selection":"over",
      "points":4.5,
      "period":0,
      "payout":"5.630"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":1.4911,
      "selection":"under",
      "points":3.5,
      "period":0,
      "payout":"1.434"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":3.0363,
      "selection":"over",
      "points":3.5,
      "period":0,
      "payout":"2.920"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":1.5889,
      "selection":"under",
      "points":3.25,
      "period":0,
      "payout":"1.537"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":2.6981,
      "selection":"over",
      "points":3.25,
      "period":0,
      "payout":"2.610"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":1.7419,
      "selection":"under",
      "points":3,
      "period":0,
      "payout":"1.684"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":2.348,
      "selection":"over",
      "points":3,
      "period":0,
      "payout":"2.270"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":2,
      "selection":"under",
      "points":2.75,
      "period":0,
      "payout":"1.943"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":2,
      "selection":"over",
      "points":2.75,
      "period":0,
      "payout":"1.943"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":2.2565,
      "selection":"under",
      "points":2.5,
      "period":0,
      "payout":"2.180"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":1.7959,
      "selection":"over",
      "points":2.5,
      "period":0,
      "payout":"1.735"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":2.6818,
      "selection":"under",
      "points":2.25,
      "period":0,
      "payout":"2.590"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":1.5946,
      "selection":"over",
      "points":2.25,
      "period":0,
      "payout":"1.540"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":4.5028,
      "selection":"under",
      "points":1.5,
      "period":0,
      "payout":"4.340"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"total",
      "odd":1.2855,
      "selection":"over",
      "points":1.5,
      "period":0,
      "payout":"1.239"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"moneyline",
      "odd":5.8775,
      "selection":"away",
      "points":"",
      "period":0,
      "payout":"5.700"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"moneyline",
      "odd":1.6519,
      "selection":"home",
      "points":"",
      "period":0,
      "payout":"1.602"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"moneyline",
      "odd":4.4545,
      "selection":"draw",
      "points":"",
      "period":0,
      "payout":"4.320"
   },
   {
      "home":"legia warsaw",
      "away":"cracovia krakow",
      "sportID":29,
      "timestamp":1602267300000,
      "eventID":1186957014,
      "eventName":"legia warsaw - cracovia krakow",
      "type":"spread",
      "odd":1.5158,
      "selection":"away",
      "points":0.75,
      "period":1,
      "payout":"1.465"
   }
]
  

Оба json получили значение «Home / Away», которое довольно похоже, мне нужно найти все записи, где один из них включен в другой

Я также обнаружил, что foreach с использованием map быстрее, чем цикл вокруг json, поэтому я меняю его на MAP

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

1. итак, 2 json не имеют одинаковых свойств?

2. Пожалуйста, поделитесь образцом из 2 объектов и ожидаемым результатом. Почему требуется преобразование из объекта в карту?

3. @OmriAttiya Мне нужно проверить, включен ли object1.home.в object2.home или включен ли object2.home в object1.home, поэтому я не могу просто преобразовать его в строку и сравнить

4. В вашем коде выше, в ваших forEach циклах, вы используете p and t , но не i1 and i2 . Вы уверены, что это правильно? p и t каждый из них должен быть индексами — числами — и, следовательно, p.home и t.eventStart и все эти другие вещи не будут существовать для этих переменных…

5. @adiga я уже поделился в посте

Ответ №1:

Здесь я разделил home s и away на Set s, чем проверил, идентичны ли наборы. Я думаю, что этот подход будет быстрее, поскольку он не перебирает O(n^2) значения.

Проверьте это

 let map1Homes = new Set(Map1.map(p => p.home));
let map2Homes = new Set(Map2.map(p => p.home));
let map1Away = new Set(Map1.map(p => p.away));
let map2Away = new Set(Map2.map(p => p.away));

function eqSet(as, bs) {
  if (as.size !== bs.size) return false;
  for (let a of as)
    if (!bs.has(a)) return false;
  return true;
}

if (eqSet(map1Homes, map2Homes) amp;amp; eqSet(map1Away, map2Away))
  console.log("homes and away are identical");  

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

1. Проблема в том, что я не могу проверить, идентичны ли home / away, я должен проверить, включены ли Map1.home в Map2.home или наоборот, или Map1.away включены в Map2.away У вас есть какие-либо идеи?

2. Вы, вероятно, не понимаете проблему, я получил 10000 записей в map1 и 10000 записей в map2 Первая запись map1 home — «Реал Мадрид», а в гостях — «Барселона» Я хочу проверить все записи в map2 и проверить, включен ли Real madrid в map2 home или map2 home включены в Realмадрид, это потому, что когда-то были разные имена, например: в map1 может быть «Барселона», а в map2 «ФК Барселона», поэтому, если я проверю это с помощью include, оно вернет значение @omriAttiya

3. @KamilZachradnik так что это опять не глубокое сравнение.. Вам нужно как-то нормализовать свои данные, если вы хотите, чтобы их было легче сравнивать