Say we have these data:
var mat = [
{
"id": "A-B",
"x": "1",
"y": "0",
"weight": "100"
},
{
"id": "A-C",
"x": "2",
"y": "0",
"weight": "77"
},
{
"id": "A-D",
"x": "3",
"y": "0",
"weight": "95"
},
{
"id": "A-E",
"x": "4",
"y": "0",
"weight": "18"
},
{
"id": "B-C",
"x": "1",
"y": "2",
"weight": "3"
},
{
"id": "D-F",
"x": "5",
"y": "3",
"weight": "18"
},
{
"id": "B-A",
"x": "0",
"y": "1",
"weight": "10"
},
{
"id": "C-A",
"x": "0",
"y": "2",
"weight": "7"
},
{
"id": "C-B",
"x": "2",
"y": "1",
"weight": "1"
},
{
"id": "D-A",
"x": "0",
"y": "3",
"weight": "5"
},
{
"id": "E-A",
"x": "0",
"y": "4",
"weight": "18"
},
{
"id": "F-D",
"x": "3",
"y": "5",
"weight": "1"
}
]
My task is to compare each object with its counterpart — i.e. compare A-B
with B-A
etc. Note that for each pair, the x
value of one is the y
value of the other, and the y
of one is the x
of the other. I want to only keep elements that have the higher weight
of their pair. If a pair has the same value of weight
- as you see with A-E
and E-A
then both are discarded.
I am very unfamiliar with JavaScript. This is how I achieved this, but I have to feel like there is a better (i.e. less code, faster) way of doing it. Also apologies if my javascript terminology is wrong.
// First I stored variables as vectors
var x = mat.map(function(x) {return x.x;});
var y = mat.map(function(x) {return x.y;});
var weights = mat.map(function(x) {return x.weight;});
// create a sequence of indices the length of the original array
var seq = [];
for (var i = 0; i < x.length; ++i) seq.push(i)
The strategy is to find the indices where each value of x
is matched in y
and vise-versa. I use the helper function below to find which index is true for both for all:
// This is a Function to find matches
Array.prototype.diff = function(arr2) {
var ret = [];
this.sort();
arr2.sort();
for(var i = 0; i < this.length; i += 1) {
if(arr2.indexOf( this[i] ) > -1){
ret.push( this[i] );
}
}
return ret;
};
Here, I go step by step to find the index that matches (i.e. is the opposite id
):
// create a sequence
var seq = [];
for (var i = 0; i < x.length; ++i) seq.push(i)
var seqindices = [];
for(var j=0; j < seq.length; j++) {
var indicesy = [];
for(var i=0; i<x.length;i++) {
if (y[i] === x[j]) indicesy.push(i);
}
var indicesx = [];
for(var i=0; i<x.length;i++) {
if (x[i] === y[j]) indicesx.push(i);
}
seqindices.push(indicesx.diff(indicesy));
}
// seqindices
// 6,7,9,10,8,11,0,1,4,2,3,5
Now I compare the weights of each against its matching index and only keep weights if greater, remove if equal to or lower.
var matres = [];
for(var i=0; i<seqindices.length;i++) {
if (weights[i] > weights[seqindices[i]]) matres.push(mat[i]);
}
This gives the following result:
[
{
"id": "A-B",
"x": "1",
"y": "0",
"weight": "100"
},
{
"id": "A-C",
"x": "2",
"y": "0",
"weight": "77"
},
{
"id": "A-D",
"x": "3",
"y": "0",
"weight": "95"
},
{
"id": "B-C",
"x": "1",
"y": "2",
"weight": "3"
},
{
"id": "D-F",
"x": "5",
"y": "3",
"weight": "18"
}
]
I have to believe I have gone a really long way round to get this result. Hopefully someone can advise a better way.