I have two arrays: First array :
SelectedRows=
[
{
"NR":"4",
"KUNNR":"9?AMT132",
"NAME":" AUTO TOURING HANDELS GES.M.B.H.",
"LATLON":[
15.4114217,
47.0664085
],
"LIN":"LIN097"
},
{
"NR":"3",
"KUNNR":"9Z?CH005",
"NAME":" Z?CHNER ERDBAU U TRANSPORT GMBH",
"LATLON":[
13.4216536,
47.3747925
],
"LIN":"LIN099"
},
{
"NR":"2",
"KUNNR":"9SMTA001",
"NAME":" SMT AUTOTEILE",
"LATLON":[
13.2277803,
47.9525892
],
"LIN":"LIN0102"
},
{
"NR":"1",
"KUNNR":"9REIT051",
"NAME":" W.REITINGER GMBH",
"LATLON":[
14.4017044,
48.2213305
],
"LIN":"LIN0103"
}
]
Second array is
LOCATIONS =
[
[
15.4114217,
47.0664085
],
[
14.4017044,
48.2213305
],
[
13.2277803,
47.9525892
],
[
13.4216536,
47.3747925
]
]
I need to sort the first array (SelectedRows) on matching values from SelectedRows.LATLON on the second array(LOCATIONS)
I tried to do:
var Output= LOCATIONS.filter(function(obj) {
return SelectedRows.LATLON.indexOf(obj) == -1;
});
but it did not work. SO if anyone can give me an advice I will be so gratefull. Sorry for my bad english, to get the idea I am posting the expected output:
Expected output :
Output=[
{
"NR":"4",
"KUNNR":"9?AMT132",
"NAME":" AUTO TOURING HANDELS GES.M.B.H.",
"LATLON":[
15.4114217,
47.0664085
],
"LIN":"LIN097"
},
{
"NR":"1",
"KUNNR":"9REIT051",
"NAME":" W.REITINGER GMBH",
"LATLON":[
14.4017044,
48.2213305
],
"LIN":"LIN0103"
},
{
"NR":"2",
"KUNNR":"9SMTA001",
"NAME":" SMT AUTOTEILE",
"LATLON":[
13.2277803,
47.9525892
],
"LIN":"LIN0102"
},
{
"NR":"3",
"KUNNR":"9Z?CH005",
"NAME":" Z?CHNER ERDBAU U TRANSPORT GMBH",
"LATLON":[
13.4216536,
47.3747925
],
"LIN":"LIN099"
}]
Thanks for your help
CodePudding user response:
what you should be doing is to map LOCATIONS
in the map you find the appropriate item in SelectedRows
...
be aware that [1,2] !== [1,2]
so you can't compare arrays in your find, since you'll never find anything - either compare each element of the arrays, or, in this case, you could check if array1.join() === array2.join()
const SelectedRows = [ { "NR":"4", "KUNNR":"9?AMT132", "NAME":" AUTO TOURING HANDELS GES.M.B.H.", "LATLON":[ 15.4114217, 47.0664085 ], "LIN":"LIN097" }, { "NR":"3", "KUNNR":"9Z?CH005", "NAME":" Z?CHNER ERDBAU U TRANSPORT GMBH", "LATLON":[ 13.4216536, 47.3747925 ], "LIN":"LIN099" }, { "NR":"2", "KUNNR":"9SMTA001", "NAME":" SMT AUTOTEILE", "LATLON":[ 13.2277803, 47.9525892 ], "LIN":"LIN0102" }, { "NR":"1", "KUNNR":"9REIT051", "NAME":" W.REITINGER GMBH", "LATLON":[ 14.4017044, 48.2213305 ], "LIN":"LIN0103" } ], LOCATIONS = [ [ 15.4114217, 47.0664085 ], [ 14.4017044, 48.2213305 ], [ 13.2277803, 47.9525892 ], [ 13.4216536, 47.3747925 ] ]
const output = LOCATIONS.map(
a=>SelectedRows.find(({LATLON}) => LATLON.join() === a.join())
);
console.log(output);
.as-console-wrapper {max-height: 100%!important; top:0; }
.as-console-row::after { display:none !important; }
Although, for truly readable code
const SelectedRows = [ { "NR":"4", "KUNNR":"9?AMT132", "NAME":" AUTO TOURING HANDELS GES.M.B.H.", "LATLON":[ 15.4114217, 47.0664085 ], "LIN":"LIN097" }, { "NR":"3", "KUNNR":"9Z?CH005", "NAME":" Z?CHNER ERDBAU U TRANSPORT GMBH", "LATLON":[ 13.4216536, 47.3747925 ], "LIN":"LIN099" }, { "NR":"2", "KUNNR":"9SMTA001", "NAME":" SMT AUTOTEILE", "LATLON":[ 13.2277803, 47.9525892 ], "LIN":"LIN0102" }, { "NR":"1", "KUNNR":"9REIT051", "NAME":" W.REITINGER GMBH", "LATLON":[ 14.4017044, 48.2213305 ], "LIN":"LIN0103" } ], LOCATIONS = [ [ 15.4114217, 47.0664085 ], [ 14.4017044, 48.2213305 ], [ 13.2277803, 47.9525892 ], [ 13.4216536, 47.3747925 ] ]
const output = LOCATIONS.map(([tgtLat, tgtLon]) =>
SelectedRows.find(
({ LATLON: [lat, lon] }) => tgtLat === lat && tgtLon === lon
)
);
console.log(output);
.as-console-wrapper {max-height: 100%!important; top:0; }
.as-console-row::after { display:none !important; }
CodePudding user response:
Following code is a bit dirty, but it works:
LOCATIONS_ORDER = LOCATIONS.map(e => `${e[0]};${e[1]}`);
SelectedRows.forEach(e => e.index = LOCATIONS_ORDER.indexOf(`${e.LATLON[0]};${e.LATLON[1]}`));
SelectedRows.sort((a,b) => a.index-b.index);
console.log(SelectedRows);
CodePudding user response:
The fastest way (at least asymptotically) to do this in O(n)
time given you have n
elements both in selectedRows
and locations
is the following.
- Loop over locations which is the correct order and map the location values to the index they are (supposed to be) at.
You cannot use the array as such for this as arrays cannot be compared using
Object.is()
whichMap
uses internally. So you could for example use a concatenated string here. There may be better/ cleaner options but this is simple and does the job. This will takeO(n)
.
The map then will look like this:
Map(4) {
'15.4114217,47.0664085' => 0,
'14.4017044,48.2213305' => 1,
'13.2277803,47.9525892' => 2,
'13.4216536,47.3747925' => 3
}
- Loop through the
selectedRows
and for each object determine it's key which is again the location concatenated and using that key get the index the object is supposed to be at inO(1)
. If the current index and the target index match everything is fine. If not, we need to swap the object to the target index which is obviously done inO(1)
. This will in total also takeO(n)
.
Done. Combined the steps will take O(n)
time and it will therefore be a asymptotically optimal algorithm.
const selectedRows =
[
{
"NR":"4",
"KUNNR":"9?AMT132",
"NAME":" AUTO TOURING HANDELS GES.M.B.H.",
"LATLON":[
15.4114217,
47.0664085
],
"LIN":"LIN097"
},
{
"NR":"3",
"KUNNR":"9Z?CH005",
"NAME":" Z?CHNER ERDBAU U TRANSPORT GMBH",
"LATLON":[
13.4216536,
47.3747925
],
"LIN":"LIN099"
},
{
"NR":"2",
"KUNNR":"9SMTA001",
"NAME":" SMT AUTOTEILE",
"LATLON":[
13.2277803,
47.9525892
],
"LIN":"LIN0102"
},
{
"NR":"1",
"KUNNR":"9REIT051",
"NAME":" W.REITINGER GMBH",
"LATLON":[
14.4017044,
48.2213305
],
"LIN":"LIN0103"
}
]
const locations =
[
[
15.4114217,
47.0664085
],
[
14.4017044,
48.2213305
],
[
13.2277803,
47.9525892
],
[
13.4216536,
47.3747925
]
]
console.log("Previous", selectedRows);
const indexMap = new Map();
// Map values to indices
locations.forEach((loc, idx) => indexMap.set(`${loc[0]},${loc[1]}`, idx));
// put each object to the correct position
selectedRows.forEach((row , i) => {
// concatenate lookup key
const key = `${row.LATLON[0]},${row.LATLON[1]}`;
// check if value is actually in map => should always be the case (assumption: locations and showLocation contain the same locations)
if(indexMap.has(key)){
const targetIndex = indexMap.get(key);
// check if the object is at the right position
if(!targetIndex === i){
// position is wrong => swap positions
const temp = selectedRows[i];
selectedRows[i] = selectedRows[targetIndex];
selectedRows[targetIndex] = temp;
}
}
})
console.log("After", selectedRows);
Note: you would need to make sure that the two variables
locations
andselectedRows
actually contain the same locations and are of equal length.