Related
This question already has answers here:
Sort an array of arrays in JavaScript
(4 answers)
Closed 1 year ago.
I have one array that holds multiple arrays that contain two numbers. I want to sort this array by ascending numbers.
This is how I'm creating the array of arrays. I start with two arrays, one holding the key and one holding the value. Then I join those two arrays into an object of key value pairs. The I convert that object into the new array of arrays.
keySliceArray.forEach((key, i) => result[key] = valueSliceArray[i])
console.log(result)
// This is the output of result
{
"73": 4028.4844548885576,
"81": 230.69935926538437,
"74.8": 3173.9828083733455,
"78.4": 1464.9795153429131,
"82.4": 0,
"77.2": 2034.647279686391,
"75.6": 2794.2042988110297,
"76.6": 2319.4811618581325,
"68.7": 6069.793943786011,
"69.3": 5784.960061614278,
"73.6": 3743.6505727168224,
"69.1": 5879.904689004858,
"74.5": 3316.399749459213,
"80.6": 420.58861404654635,
"80.1": 657.9501825229945,
"71.8": 4598.152219232035,
"76.5": 2366.9534755534196,
"80.4": 515.5332414371196,
"83.1": 0,
"83.8": 0,
"81.7": 0,
"83.3": 0,
"83.7": 0,
"71.1": 4930.458415099063,
"74.7": 3221.4551220686317,
"73.2": 3933.539827497977,
"75.7": 2746.7319851157354,
"78.8": 1275.0902605617584,
"77.4": 1939.7026522958095,
"78.6": 1370.034887952339
}
// This is how I'm converting the above object into an array of arrays.
var newArray = Object.keys(result).map(function (key) {
return [Number(key), result[key] ];
})
console.log(newArray)
This is the original output of the newArray variable
[
[
73,
4028.4844548885576
],
[
81,
230.69935926538437
],
[
74.8,
3173.9828083733455
],
[
78.4,
1464.9795153429131
],
[
82.4,
0
],
[
77.2,
2034.647279686391
],
[
75.6,
2794.2042988110297
],
[
76.6,
2319.4811618581325
],
[
68.7,
6069.793943786011
],
[
69.3,
5784.960061614278
],
[
73.6,
3743.6505727168224
],
[
69.1,
5879.904689004858
],
[
74.5,
3316.399749459213
],
[
80.6,
420.58861404654635
],
[
80.1,
657.9501825229945
],
[
71.8,
4598.152219232035
],
[
76.5,
2366.9534755534196
],
[
80.4,
515.5332414371196
],
[
83.1,
0
],
[
83.8,
0
],
[
81.7,
0
],
[
83.3,
0
],
[
83.7,
0
],
[
71.1,
4930.458415099063
],
[
74.7,
3221.4551220686317
],
[
73.2,
3933.539827497977
],
[
75.7,
2746.7319851157354
],
[
78.8,
1275.0902605617584
],
[
77.4,
1939.7026522958095
],
[
78.6,
1370.034887952339
]
]
I want it to look like this. I want sort the newArray variable in ascending order by the first number in each subsequent array.
[
[
68.7,
6069.793943786011
],
[
69.1,
5879.904689004858
],
[
69.3,
5784.960061614278
],
[
71.1,
4930.458415099063
],
[
71.8,
4598.152219232035
],
[
73,
4028.4844548885576
],
[
73.2,
3933.539827497977
],
[
73.6,
3743.6505727168224
],
[
74.5,
3316.399749459213
],
[
74.7,
3221.4551220686317
],
[
74.8,
3173.9828083733455
],
[
75.6,
2794.2042988110297
],
[
75.7,
2746.7319851157354
],
[
76.5,
2366.9534755534196
],
[
76.6,
2319.4811618581325
],
[
77.2,
2034.647279686391
],
[
77.4,
1939.7026522958095
],
[
78.4,
1464.9795153429131
],
[
78.6,
1370.034887952339
],
[
78.8,
1275.0902605617584
],
[
80.1,
657.9501825229945
],
[
80.4,
515.5332414371196
],
[
80.6,
420.58861404654635
],
[
81,
230.69935926538437
],
[
81.7,
0
],
[
82.4,
0
],
[
83.1,
0
],
[
83.3,
0
],
[
83.7,
0
]
[
83.8,
0
]
]
I have tried using the sort method like this but for some reason this just returns the original array. Any advice on how to achieve this is greatly appreciated!
let sortArray = newArray.sort(function (a, b) {
return a - b
})
Your sort isn't working because you need to sort by the key of the nested object, not the nested object itself. Since your array contains tuples and you want to sort by the value of the first element in the tuple, this should work:
newArray.sort(function (a, b) {
return a[0] - b[0];
});
Also, note that Array.prototype.sort sorts the array in place.
const result = {
"73": 4028.4844548885576,
"81": 230.69935926538437,
"74.8": 3173.9828083733455,
"78.4": 1464.9795153429131,
"82.4": 0,
"77.2": 2034.647279686391,
"75.6": 2794.2042988110297,
"76.6": 2319.4811618581325,
"68.7": 6069.793943786011,
"69.3": 5784.960061614278,
"73.6": 3743.6505727168224,
"69.1": 5879.904689004858,
"74.5": 3316.399749459213,
"80.6": 420.58861404654635,
"80.1": 657.9501825229945,
"71.8": 4598.152219232035,
"76.5": 2366.9534755534196,
"80.4": 515.5332414371196,
"83.1": 0,
"83.8": 0,
"81.7": 0,
"83.3": 0,
"83.7": 0,
"71.1": 4930.458415099063,
"74.7": 3221.4551220686317,
"73.2": 3933.539827497977,
"75.7": 2746.7319851157354,
"78.8": 1275.0902605617584,
"77.4": 1939.7026522958095,
"78.6": 1370.034887952339
}
var newArray = Object.keys(result).map(function (key) {
return [Number(key), result[key] ];
});
newArray.sort(function (a, b) {
return a[0] - b[0];
});
console.log(newArray);
I have an array of timeseries objects that I need to filter in React.
Specifically, I need to return an array containing a filtered subset of the array of objects, based on the value of device_id being equal to e.g. 7F34B296.
The raw array looks as below:
[
{
"label": "time_stamp",
"data": [
"2019-04-17 21:01:25.673949957+02:00",
"2019-04-17 21:01:30.673949957+02:00",
"2019-04-17 21:01:35.673949957+02:00",
"2019-04-17 21:01:40.673949957+02:00",
"2019-04-17 21:01:45.673949957+02:00"
]
},
{
"label": "device_id",
"data": [
"7F34B296",
"7F34B296",
"7F34B296",
"AB22438D",
"AB22438D"
]
},
{
"label": "parameter_x",
"data": [
"929.1965116",
"927.5152582",
"928.7476077",
"1919.2691327",
"1918.7047619"
]
}
]
The intended output array (after filtering) looks as below:
[
{
"label": "time_stamp",
"data": [
"2019-04-17 21:01:25.673949957+02:00",
"2019-04-17 21:01:30.673949957+02:00",
"2019-04-17 21:01:35.673949957+02:00"
]
},
{
"label": "device_id",
"data": [
"7F34B296",
"7F34B296",
"7F34B296"
]
},
{
"label": "parameter_x",
"data": [
"929.1965116",
"927.5152582",
"928.7476077"
]
}
]
I tried using various methods, including below - but I seem unable to get the desired result. I think I'm missing the part on how to handle that the filtering of the entire array of objects should depend on the value of a subset of one of the objects.
const filters = [
{
predicateFn: data => data.data == "7F34B296"
}
];
function getFilteredPersons(filters) {
return datasets.filter(p => filters.every(filter => filter.predicateFn(p)));
}
console.log(getFilteredPersons(filters));
Maybe try to map your data to some kind of the structure f.e.:
const joinedData = []
data.map((element) =>
element.data.map((e, i) => joinedData[i] = { [element.label]: e, ...joinedData[i]}))
Then you will have transformed data in shape:
[
{
parameter_x: '929.1965116',
device_id: '7F34B296',
time_stamp: '2019-04-17 21:01:25.673949957+02:00'
},
{
parameter_x: '927.5152582',
device_id: '7F34B296',
time_stamp: '2019-04-17 21:01:30.673949957+02:00'
},
{
parameter_x: '928.7476077',
device_id: '7F34B296',
time_stamp: '2019-04-17 21:01:35.673949957+02:00'
},
{
parameter_x: '1919.2691327',
device_id: 'AB22438D',
time_stamp: '2019-04-17 21:01:40.673949957+02:00'
},
{
parameter_x: '1918.7047619',
device_id: 'AB22438D',
time_stamp: '2019-04-17 21:01:45.673949957+02:00'
}
]
which will be easier to filter
If your data object is always structured same way (3 elements each on same place), then you can do something like this:
const data = [
{
"label": "time_stamp",
"data": [
"2019-04-17 21:01:25.673949957+02:00",
"2019-04-17 21:01:30.673949957+02:00",
"2019-04-17 21:01:35.673949957+02:00",
"2019-04-17 21:01:40.673949957+02:00",
"2019-04-17 21:01:45.673949957+02:00"
]
},
{
"label": "7F34B296",
"data": [
"7F34B296",
"7F34B296",
"7F34B296",
"AB22438D",
"AB22438D"
]
},
{
"label": "parameter_x",
"data": [
"929.1965116",
"927.5152582",
"928.7476077",
"1919.2691327",
"1918.7047619"
]
}
]
const mainData = data[1];
const deviceId = mainData.label;
const indexes = mainData.data.filter((item) => item === deviceId).map((e, idx, array) => idx);
const result = data.map((value) => {
const filteredData = value.data.filter((item, idx) => {
return indexes.some((e => idx === e));
})
return {
...value,
data: filteredData
}
});
console.log(result)
Basically just find indexes of device_id in second element of array, and then extract values on those indexes of device_id, time_stamp and parameter_x data properties.
Although this might work, I'd suggest restructuring your data because this is quite complicated structure.
We can use forEach method with splice to get desired output.
let arr = [
{
"label": "time_stamp",
"data": [
"2019-04-17 21:01:25.673949957+02:00",
"2019-04-17 21:01:30.673949957+02:00",
"2019-04-17 21:01:35.673949957+02:00",
"2019-04-17 21:01:40.673949957+02:00",
"2019-04-17 21:01:45.673949957+02:00"
]
},
{
"label": "device_id",
"data": [
"7F34B296",
"7F34B296",
"7F34B296",
"AB22438D",
"AB22438D"
]
},
{
"label": "parameter_x",
"data": [
"929.1965116",
"927.5152582",
"928.7476077",
"1919.2691327",
"1918.7047619"
]
}
]
arr.forEach( (val, index) => val.data.splice(3) )
console.log(arr)
I need help ! Can you tell me how can I get informations from this in javascript :
I would like to get the Third values from the fisrt array (121,73) and also the Fourth (99,25) . Thank you in advance !
{
"error": [],
"result": {
"XETHZEUR": [
[
1545955200,
"100.76",
"121.73",
"99.25",
"120.16",
"111.15",
"186385.05723331",
25420
],
[
1546041600,
"120.52",
"130.00",
"115.91",
"117.89",
"121.47",
"154551.36751227",
23261
],
"last": 1546387200
}
}
var feild = {
"error": [],
"result": {
"XETHZEUR": [
[
1545955200,
"100.76",
"121.73",
"99.25",
"120.16",
"111.14",
"183581.25666187",
25053
],
[
1546041600,
"120.16",
"130.00",
"115.91",
"117.89",
"121.48",
"152980.08236398",
21309
],
[
1546128000,
"117.96",
"123.75",
"112.78",
"121.99",
"119.43",
"108719.51659796",
14936
],
[
1546214400,
"121.99",
"122.30",
"113.00",
"114.96",
"118.14",
"69796.43117029",
9347
],
[
1546300800,
"114.97",
"123.90",
"114.00",
"122.46",
"119.83",
"64248.31302812",
9713
],
[
1546387200,
"122.62",
"138.80",
"121.25",
"135.57",
"131.69",
"189734.68299147",
37935
],
[
1546473600,
"135.57",
"136.25",
"128.33",
"131.45",
"132.12",
"67066.92874540",
8790
]
],
"last": 1546387200
}
}
let empty= [];
feild.result.XETHZEUR.map(e=>{
empty.push(e[2])
empty.push(e[3])
})
empty.map(e=>{
if(e=="121.73"){
console.log(e)
}
if(e=="99.25"){
console.log(e)
}
})
So I have a bunch of status codes, in an object (from an API) that returns like this:
{
"location": [
"HOME_ADDRESS_INCOMPLETE",
"HOME_MISSING_ADDRESS"
],
"basics": [
"HOME_MISSING_TYPE"
],
"description": [
"HOME_MISSING_DESCRIPTION"
],
"immersions": [
"AT_LEAST_ONE_STAY_REQUIRED",
"SIMPLE_STAY_MISSING_HOURS",
"SIMPLE_STAY_MISSING_OFFERED_LANGUAGES",
"TANDEM_STAY_MISSING_HOURS",
"TANDEM_STAY_MISSING_OFFERED_LANGUAGES",
"TANDEM_STAY_MISSING_INTERESTED_LANGUAGES",
"TEACHER_STAY_MISSING_HOURLY_PRICE",
"TEACHER_STAY_MISSING_OFFERED_LANGUAGES",
"TEACHER_STAY_MISSING_WEEKLY_PACKAGES"
],
"rooms": [
"NO_ROOMS"
],
"photos": [
"AT_LEAST_ONE_HOME_IMAGE_REQUIRED"
],
"pricing": [
"MISSING_CURRENCY",
"SERVICE_WITHOUT_PRICE",
"DISCOUNT_WITHOUT_PERCENT",
"ROOM_WITHOUT_PRICE"
]
}
The key names, like location correlate to a step in a setup wizard that the user must be placed on depending on what is missing, which is represented by constants like HOME_ADDRESS_INCOMPLETE.
What is the most terse or clear way to start with this object and one constant, like MISSING_CURRENCY, and return the name of the key to which that constant's array belongs to?
Here's what I have so far, but all it does is return the array itself:
const activeStep = Object.values(HomeStatusCodes).filter(statusArray => {
return statusArray.includes(homeActivationResponse.code)
})
Array#find (on the array of keys of that structure, from Object.keys) plus Array#indexOf should do it:
function find(value) {
return Object.keys(data).find(function(key) {
return data[key].indexOf(value) != -1;
});
}
Note that Array#find is new in ES2015, but can readily be shimmed/polyfilled.
Example:
var data = {
"location": [
"HOME_ADDRESS_INCOMPLETE",
"HOME_MISSING_ADDRESS"
],
"basics": [
"HOME_MISSING_TYPE"
],
"description": [
"HOME_MISSING_DESCRIPTION"
],
"immersions": [
"AT_LEAST_ONE_STAY_REQUIRED",
"SIMPLE_STAY_MISSING_HOURS",
"SIMPLE_STAY_MISSING_OFFERED_LANGUAGES",
"TANDEM_STAY_MISSING_HOURS",
"TANDEM_STAY_MISSING_OFFERED_LANGUAGES",
"TANDEM_STAY_MISSING_INTERESTED_LANGUAGES",
"TEACHER_STAY_MISSING_HOURLY_PRICE",
"TEACHER_STAY_MISSING_OFFERED_LANGUAGES",
"TEACHER_STAY_MISSING_WEEKLY_PACKAGES"
],
"rooms": [
"NO_ROOMS"
],
"photos": [
"AT_LEAST_ONE_HOME_IMAGE_REQUIRED"
],
"pricing": [
"MISSING_CURRENCY",
"SERVICE_WITHOUT_PRICE",
"DISCOUNT_WITHOUT_PERCENT",
"ROOM_WITHOUT_PRICE"
]
};
function find(value) {
return Object.keys(data).find(function(key) {
return data[key].indexOf(value) != -1;
});
}
console.log(find("MISSING_CURRENCY"));
Even more terse when you use ES2015 syntax:
const find = value =>
Object.keys(data).find(key => data[key].indexOf(value) != -1);
(Yes, that's really a function.) Here's a live version of that for browsers that support ES2015:
var data = {
"location": [
"HOME_ADDRESS_INCOMPLETE",
"HOME_MISSING_ADDRESS"
],
"basics": [
"HOME_MISSING_TYPE"
],
"description": [
"HOME_MISSING_DESCRIPTION"
],
"immersions": [
"AT_LEAST_ONE_STAY_REQUIRED",
"SIMPLE_STAY_MISSING_HOURS",
"SIMPLE_STAY_MISSING_OFFERED_LANGUAGES",
"TANDEM_STAY_MISSING_HOURS",
"TANDEM_STAY_MISSING_OFFERED_LANGUAGES",
"TANDEM_STAY_MISSING_INTERESTED_LANGUAGES",
"TEACHER_STAY_MISSING_HOURLY_PRICE",
"TEACHER_STAY_MISSING_OFFERED_LANGUAGES",
"TEACHER_STAY_MISSING_WEEKLY_PACKAGES"
],
"rooms": [
"NO_ROOMS"
],
"photos": [
"AT_LEAST_ONE_HOME_IMAGE_REQUIRED"
],
"pricing": [
"MISSING_CURRENCY",
"SERVICE_WITHOUT_PRICE",
"DISCOUNT_WITHOUT_PERCENT",
"ROOM_WITHOUT_PRICE"
]
};
const find = value =>
Object.keys(data).find(key => data[key].indexOf(value) != -1);
console.log(find("MISSING_CURRENCY"));
You could iterate the keys and find the one which property includes the wanted item.
function getKey(object, item) {
return Object.keys(object).find(k => object[k].includes(item));
}
var data = { "location": ["HOME_ADDRESS_INCOMPLETE", "HOME_MISSING_ADDRESS"], "basics": ["HOME_MISSING_TYPE"], "description": ["HOME_MISSING_DESCRIPTION"], "immersions": ["AT_LEAST_ONE_STAY_REQUIRED", "SIMPLE_STAY_MISSING_HOURS", "SIMPLE_STAY_MISSING_OFFERED_LANGUAGES", "TANDEM_STAY_MISSING_HOURS", "TANDEM_STAY_MISSING_OFFERED_LANGUAGES", "TANDEM_STAY_MISSING_INTERESTED_LANGUAGES", "TEACHER_STAY_MISSING_HOURLY_PRICE", "TEACHER_STAY_MISSING_OFFERED_LANGUAGES", "TEACHER_STAY_MISSING_WEEKLY_PACKAGES"], "rooms": ["NO_ROOMS"], "photos": ["AT_LEAST_ONE_HOME_IMAGE_REQUIRED"], "pricing": ["MISSING_CURRENCY", "SERVICE_WITHOUT_PRICE", "DISCOUNT_WITHOUT_PERCENT", "ROOM_WITHOUT_PRICE"] };
console.log(getKey(data, 'MISSING_CURRENCY'));
I'd go for a lookup map:
const stepByStatusCode = new Map()
for (const step in HomeStatusCodes) {
for (const code of HomeStatusCodes[step])
stepByStatusCode.set(code, step);
which you then can use in the most terse way
const activeStep = stepByStatusCode.get(homeActivationResponse.code);
I have these lines called:
loadMapLayer(lines1);
loadMapLayer(lines2);
routesLayerGroup = L.layerGroup(routesMap).addTo(map);
and these functions:
function loadMapLayer(routesServer) {
for (var i = 0; i < routesServer.length; i++) {
if (routesServer[i].properties["type"] == "old") {
addRoute(routesServer[i], astar_style);
}
if (routesServer[i].properties["type"] == "new") {
addRoute(routesServer[i], bidi_style);
}
}
}
function addRoute(route, style) {
routeMap = L.geoJson(route, {
style: style
})
routesMap.push(routeMap);
}
var astar_style = {
"color": "red",
"weight": 5,
"opacity": 0.65
};
var bidi_style = {
"color": "yellow",
"weight": 5,
"opacity": 0.65
};
I debug and see addRoute(routesServer[i], astar_style); and addRoute(routesServer[i], bidi_style); are called, but on my map, all the routes are yellow. How can I fix this?
I have spread lines1 and lines2 to different start points and yet they are all yellow and not red.
See image:
Update:
I see the json I have doesn't fit to the leaflet object. route.properties["type"] returns undefined.
Why does parsing fail?
var lines2= [
{
"type": "LineString",
"stroke": "true",
"properties": {
"type": "new",
"alt_id": 0
},
"coordinates": [
[
-0.19260167,
51.60275078
],
[
-0.18776697865776057,
51.51378379618606
],
[
-0.1868361042991638,
51.51386350952752
],
[
-0.18610120486834886,
51.513949508589846
],
[
-0.1860126676721192,
51.5139587109798
],
[
-0.18503012435859684,
51.51407686278982
],
[
-0.1844715979628327,
51.512811327510235
],
[
-0.18438086668647774,
51.51260842537383
],
[
-0.18421945,
51.51219938
],
[
-0.18371567893492108,
51.51073654980558
],
[
-0.18367635639669866,
51.51051275309526
],
[
-0.18278586300375,
51.510576187561
],
[
-0.18001538515091456,
51.51099998178699
],
[
-0.17978213237246937,
51.511036465619824
],
[
-0.17754539181132,
51.511350689722
],
[
-0.17667213783413,
51.511469143954
],
[
-0.17605905,
51.5116603
],
[
-0.17599639,
51.51194254
],
[
-0.17595176,
51.5121633
],
[
-0.17576338,
51.51264908
],
[
-0.17526760982170084,
51.5127504306477
],
[
-0.17448749264235414,
51.512204418972296
],
[
-0.17366204281806927,
51.51184552510889
],
[
-0.17229427780151832,
51.51200799788328
],
[
-0.16879990859832764,
51.51236051966681
],
[
-0.1676648163893128,
51.51245737406541
],
[
-0.1680470167036,
51.513849950881
],
[
-0.16816666875569,
51.513895844874
],
[
-0.16806539030114,
51.513971712699
],
[
-0.16809616949711467,
51.514138665582394
],
[
-0.1670313325182289,
51.514318938428715
],
[
-0.16644342299303297,
51.51441707946363
],
[
-0.16557087028261,
51.515078135345
],
[
-0.1648144873404,
51.515515453665
],
[
-0.1645753,
51.51564283
],
[
-0.16412506782526948,
51.51588568011996
],
[
-0.16395137600442822,
51.51595497980128
],
[
-0.16371551862975017,
51.51601826243177
],
[
-0.16363422357553456,
51.51604007459718
],
[
-0.16248937,
51.51625975
],
[
-0.1618248006248185,
51.51636682729078
],
[
-0.16144195106065864,
51.516433011832596
],
[
-0.16079458,
51.51653877
],
[
-0.16049632,
51.51658803
],
[
-0.16013511,
51.51664799
],
[
-0.15952000080734252,
51.516760840000025
],
[
-0.15903941,
51.51683111
],
[
-0.15857268,
51.51690964
],
[
-0.15818745419376345,
51.51697458112003
],
[
-0.15752605,
51.51708608
],
[
-0.15710946680072266,
51.51715610050016
],
[
-0.15539842,
51.51744437
],
[
-0.1547544976616,
51.517548545154
],
[
-0.15355205591518,
51.517754494854
],
[
-0.15284529383976753,
51.51787800540975
]
]
},
Your code seems to do what you expect: http://jsfiddle.net/ve2huzxw/181/
Note that you could also simplify your code. The L.geoJson factory can directly manage your routesServer array of GeoJSON objects, and receive a style function which gets the feature as single argument.
function loadMapLayer(routesServer) {
routeMap = L.geoJson(routesServer, {
style: function(route) {
return route.properties["type"] == "old" ?
astar_style : bidi_style;
}
})
routesMap.push(routeMap);
}
Demo: http://jsfiddle.net/ve2huzxw/183/