Joining two datasets using javascript

I have two datasets that look like this:

var gatePos = [ 
    { gate: 1, x: 1177, y: 200 },
    { gate: 2, x: 1109, y: 200 },
    { gate: 3, x: 1042, y: 200 },
    { gate: 4, x: 975, y: 200 },
    { gate: 5, x: 908, y: 200 },
    { gate: 6, x: 842, y: 200 },
    { gate: 7, x: 774, y: 200 },
    { gate: 8, x: 708, y: 200 },
    { gate: 9, x: 641, y: 200 },
    { gate: 10, x: 578, y: 200 }
 ];

and

[
  {
    "gate": "8B",
    "value": 126
  },
  {
    "gate": "9B",
    "value": 268
  },
  {
    "gate": "10B",
    "value": 91
  },
  {
    "gate": "21B",
    "value": 9
  },
  {
    "gate": "24B",
    "value": 1
  },
  {
    "gate": "JC",
    "value": 48352
  },
  {
    "gate": "LOCALISER",
    "value": 22
  },
  {
    "gate": 1,
    "value": 34351
  },
  {
    "gate": 2,
    "value": 37855
  },
  {
    "gate": 3,
    "value": 38462
  },
  {
    "gate": 4,
    "value": 38126
  },
  {
    "gate": 5,
    "value": 40089
  }

,
  {
    "gate": 6,
    "value": 39295
  },
  {
    "gate": 7,
    "value": 36581
  },
  {
    "gate": 8,
    "value": 33908
  },
  {
    "gate": 9,
    "value": 31187
  },
  {
    "gate": 10,
    "value": 22915
  },
  {
    "gate": 11,
    "value": 5164
  },
  {
    "gate": 12,
    "value": 9533
  },
  {
    "gate": 13,
    "value": 6454
  },
  {
    "gate": 14,
    "value": 5003
  },
  {
    "gate": 15,
    "value": 1
  },
  {
    "gate": 21,
    "value": 19804
  },
  {
    "gate": 22,
    "value": 21239
  },
  {
    "gate": 23,
    "value": 17779
  },
  {
    "gate": 24,
    "value": 15213
  },
  {
    "gate": "-",
    "value": 37562
  }
]

They have "Gate" as the key. I wish to "Left join" in SQL terms my datasets, and have an output like so:

[{ gate: 1, x: 100, y: 200, value: 999 },
{ gate: 2, x: 150, y: 200, value: 1000}] 
... etc

Can anyone point me in the right direction to achieve this? I'm using d3.js mainly but I understand it doesn't have support for this type of thing so I would like to achieve in standard js, even if you can give me some terms to search or something would be a massive help.

If you are not familiar with SQL's left join, I would like my new array to contain ALL values from var gatePos but ONLY THE MATCHING values from the second dataset.

Answers:

Answer

You could mimic left outer join with a function and a hash table for item with same join key.

var gatePos = [{ gate: 1, x: 1177, y: 200 }, { gate: 2, x: 1109, y: 200 }, { gate: 3, x: 1042, y: 200 }, { gate: 4, x: 975, y: 200 }, { gate: 5, x: 908, y: 200 }, { gate: 6, x: 842, y: 200 }, { gate: 7, x: 774, y: 200 }, { gate: 8, x: 708, y: 200 }, { gate: 9, x: 641, y: 200 }, { gate: 10, x: 578, y: 200 }],
    gateValues = [{ gate: "8B", value: 126 }, { gate: "9B", value: 268 }, { gate: "10B", value: 91 }, { gate: "21B", value: 9 }, { gate: "24B", value: 1 }, { gate: "JC", value: 48352 }, { gate: "LOCALISER", value: 22 }, { gate: 1, value: 34351 }, { gate: 2, value: 37855 }, { gate: 3, value: 38462 }, { gate: 4, value: 38126 }, { gate: 5, value: 40089 }, { gate: 6, value: 39295 }, { gate: 7, value: 36581 }, { gate: 8, value: 33908 }, { gate: 9, value: 31187 }, { gate: 10, value: 22915 }, { gate: 11, value: 5164 }, { gate: 12, value: 9533 }, { gate: 13, value: 6454 }, { gate: 14, value: 5003 }, { gate: 15, value: 1 }, { gate: 21, value: 19804 }, { gate: 22, value: 21239 }, { gate: 23, value: 17779 }, { gate: 24, value: 15213 }, { gate: "-", value: 37562 }],
    result = function (left, right, on, key) {
        var hash = Object.create(null),
            result = left.map(function (o) {
                return hash[o[on]] = Object.assign({}, o);
            });
        right.forEach(function (o) {
            if (hash[o[on]]) {
                hash[o[on]][key] = o[key];
            }
        });
        return result;
    }(gatePos, gateValues, 'gate', 'value');

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

Answer

Check if this code works for you:

var gatePos = [{ gate: 1, x: 1177, y: 200 },{ gate: 2, x: 1109, y: 200 },{ gate: 3, x: 1042, y: 200 },{ gate: 4, x: 975, y: 200 },{ gate: 5, x: 908, y: 200 },{ gate: 6, x: 842, y: 200 },{ gate: 7, x: 774, y: 200 },{ gate: 8, x: 708, y: 200 },{ gate: 9, x: 641, y: 200 },{ gate: 10, x: 578, y: 200 }];
var gatePosValue = [{"gate":"8B","value":126},{"gate":"9B","value":268},{"gate":"10B","value":91},{"gate":"21B","value":9},{"gate":"24B","value":1},{"gate":"JC","value":48352},{"gate":"LOCALISER","value":22},{"gate":1,"value":34351},{"gate":2,"value":37855},{"gate":3,"value":38462},{"gate":4,"value":38126},{"gate":5,"value":40089},{"gate":6,"value":39295},{"gate":7,"value":36581},{"gate":8,"value":33908},{"gate":9,"value":31187},{"gate":10,"value":22915},{"gate":11,"value":5164},{"gate":12,"value":9533},{"gate":13,"value":6454},{"gate":14,"value":5003},{"gate":15,"value":1},{"gate":21,"value":19804},{"gate":22,"value":21239},{"gate":23,"value":17779},{"gate":24,"value":15213},{"gate":"-","value":37562}];
var gatePosResult = [];

for(var i = 0; i < gatePos.length; i++) {
    gatePosResult[i] = {};
    for(var key in gatePos[i]) {
        if(gatePos[i].hasOwnProperty(key)) {
            gatePosResult[i][key] = gatePos[i][key];
        }
    }     
    gatePosResult[i].value = null;
    for(var j = 0; j < gatePosValue.length; j++) {
        if(gatePosValue[j].gate === gatePosResult[i].gate) {
            gatePosResult[i].value = gatePosValue[j].value;
            break;
        }
    }
}
console.log(gatePosResult);
Answer

You can use resuce and find like:

let result = gatePos.reduce(function(res, obj) {     // for each object obj in gatePos array
    var found = otherArray.find(function(o) {        // check if there is an object in the other array (rename the variable name before use)
        return o.gate == obj.gate;                   // that has the same gate as the object obj
    });
    if(found) {                                      // if we found one
        var newObj = Object.assign({}, obj);         // then create a new object
        newObj.value = found.value;                  // set its value
        res.push(newObj);                            // and add it to the result array
    }
    return res;
}, []);

Note: I refered to the second array from your question as otherArray. Rename the variable name to match the real variable used to hold that array.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.