How to iterate an array of indexed objects - javascript

I have an array of objects that is indexed and I want to iterate through it to convert it to a new flat array.
This is the array of objects:
"attentionSchedules": [
{
"room": "1",
"schedules": [
{
"days": [
"SA",
"WE"
],
"_id": "6271xxxx",
"initialTimeStr": "12:00 am",
"finalTimeStr": "12:00 am",
"initialTime": "2022-05-03T06:00:00.000Z",
"finalTime": "2022-05-03T06:00:00.000Z"
}
],
"place": {
"loc": {
"type": "Point",
"coordinates": [
-88.03xxx,
15.49xxx
]
},
"_idPlace": "5d5ba845xxx",
"name": "Labs",
"address": "xxx"
},
"floor": 1
},
{
"room": "23",
"floor": 1,
"schedules": [
{
"days": [
"MO",
"TH",
"WE",
"YOU",
"FR",
"SA"
],
"_id": "62754264a627af5fc44286b3",
"initialTimeStr": "08:00 am",
"finalTimeStr": "09:00 pm",
"initialTime": "2022-05-06T14:00:00.000Z",
"finalTime": "2022-05-07T03:00:00.000Z"
}
],
"place": {
"loc": {
"type": "Point",
"coordinates": [
-88.02xxx,
15.50xxx
]
},
"_idPlace": "ba",
"name": "Labs",
"address": "xx"
}
}
],
I want to iterate over it, get its values ​​and convert it to a new object like this:
{
lng: -88.02xxx
lat: 15.50xxx
_idPlace: "ba"
}
.
.
.
N
How can I do this? I'm using angular, I'm doing the method with javascript/types Currently I did something like this:
let locCoord: any[] = [];
this.attentionSchedules?.forEach(elm => {
for (const [key, value] of Object.entries(elm.place.loc)) {
let lng = value[0];
let lat = value[1];
let dataObjLoc = {
_id: elm.place._id,
lat: lat,
lng: lng
}
locCoord.push(dataObjLoc);
}
});
console.log(locCoord);
And it returns the following:
[
{
"_idPlace": "5d5ba84531f75411f3b6417e",
"lat": "or",
"lng": "P"
},
{
"_idPlace": "5d5ba84531f75411f3b6417e",
"lat": 15.4997741,
"lng": -88.03860120000002
},
{
"_idPlace": "6109766f913cf469f6b177ba",
"lat": "or",
"lng": "P"
},
{
"_idPlace": "6109766f913cf469f6b177ba",
lat: 15.5085874,
"lng": -88.0264096
}
]
It is not what I need, since when using Object.entries it not only extracts the values ​​but also duplicates the keys. Somebody could help me? Please

I'm not sure you need to loop over Object.entries(elm.place.loc) (if I've understood the problem). I think you can just extract the values somewhat directly:
const attentionSchedules = [{"room":"1","schedules":[{"days":["SA","WE"],"_id":"6271xxxx","initialTimeStr":"12:00 am","finalTimeStr":"12:00 am","initialTime":"2022-05-03T06:00:00.000Z","finalTime":"2022-05-03T06:00:00.000Z"}],"place":{"loc":{"type":"Point","coordinates":[-88.03,15.49]},"_idPlace":"5d5ba845xxx","name":"Labs","address":"xxx"},"floor":1},{"room":"23","floor":1,"schedules":[{"days":["MO","TH","WE","YOU","FR","SA"],"_id":"62754264a627af5fc44286b3","initialTimeStr":"08:00 am","finalTimeStr":"09:00 pm","initialTime":"2022-05-06T14:00:00.000Z","finalTime":"2022-05-07T03:00:00.000Z"}],"place":{"loc":{"type":"Point","coordinates":[-88.02,15.5]},"_idPlace":"ba","name":"Labs","address":"xx"}}];
let locCoord = [];
attentionSchedules?.forEach(({ place }) => {
const [lng, lat] = place.loc.coordinates;
locCoord.push({
_id: place._idPlace,
lat: lat,
lng: lng
});
});
console.log(locCoord);

Related

String to non-array json

I have a string that looks like the following:
{
"results": [
{
"address_components": [
{
"long_name": "Ireland",
"short_name": "Ireland",
"types": [
"establishment",
"natural_feature"
]
}
],
"formatted_address": "Ireland",
"geometry": {
"bounds": {
"northeast": {
"lat": 55.38294149999999,
"lng": -5.431909999999999
},
"southwest": {
"lat": 51.4475448,
"lng": -10.4800237
}
}],
"status" : "OK"
}
I want to turn this into a json that I can easily traverse. However when I call JSON.parse() on this string I get a json array that is a pain to traverse. I want to be able to extract the lat and lng from northeast without having to loop through the entire array.
var json = `{
"results": [
{
"address_components": [
{
"long_name": "Ireland",
"short_name": "Ireland",
"types": [
"establishment",
"natural_feature"
]
}
],
"formatted_address": "Ireland",
"geometry": {
"bounds": {
"northeast": {
"lat": 55.38294149999999,
"lng": -5.431909999999999
},
"southwest": {
"lat": 51.4475448,
"lng": -10.4800237
}
}
}
}
],
"status" : "OK"
}`;
var data = JSON.parse(json);
var bounds = data.results[0].geometry.bounds;
var bound = bounds.northeast || bounds.southwest;
console.log(bound.lat, bound.lng);
If you know northeast is always an option you can simplify this to:
console.log(data.results[0].geometry.bounds.northeast);
That will give you your lat and lng.

How do I sort a GeoJSON features array by a property value?

I am looking to sort a GeoJSON file on a property so I can then slice it keeping only the top 5 features. So for example I wish to take this GeoJSON and sort the file in descending order by the incidents property:
...
[
-75.1972382872565,
39.9294288475177
]
]
]
]
},
"properties": {
"area": "",
"location": "24th St. & Wolf St.",
"perimeter": "81903.64182498",
"dist_numc": "01",
"sum_area": "",
"area_sqmi": "216350124.153",
"district_i": "",
"objectid": "321",
"globalid": "c040618c-ac93-4b22-b174-0ea08e0f805d",
"district_": "1",
"_feature_id": "1",
"_feature_id_string": "Police_Districts.1",
"dist_num": "1",
"div_code": "SPD",
"phone": "686-3010",
"incidents": 11553
}
},
...
I'm looking to basically rearrange the order of the features array so that it's in descending order and the highest incident features are first.
How would I go about this? I am used to creating a compare function and then sorting an array with something like this:
//FUNCTION: SORT
export const compare = ( a, b ) => {
if ( a.incidents < b.incidents ){
return -1;
}
if ( a.incidents > b.incidents ){
return 1;
}
return 0;
}
But in this case I need to sort a JSON and only sort an array inside of it so I am unsure how to proceed.
I set up an example where i attempt to sort via a button click but doesn't seem to be working:
https://codesandbox.io/s/slicing-geojson-qg1hb?file=/src/App.js
Consider this file as JSON. To do that, I've copied the first three data from that geojson file and store into a variable called data. So we need to sort that array according to the incidents property. Now execute javascript's sort() function to data.features. Since your data is big and you're sorting the data according to the incidents property, make sure to print only incidents property to see whether your data is being sorted or not. As StackOverflow asks limited characters(30000) in this section, I'm going to keep only the first three coordinates from every geometry property. Have a look at the snippet below:
var data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
-75.0544420852857,
40.044532749252
],
[
-75.054816199384,
40.0441717116827
],
[
-75.0551367855513,
40.0438732632911
],
]
]
]
},
"properties": {
"area": "",
"location": "Harbison Ave. & Levick St.",
"perimeter": "63587.3693993",
"dist_numc": "02",
"sum_area": "",
"area_sqmi": "192346097.032",
"district_i": "",
"objectid": "322",
"globalid": "95200c4a-2617-47c2-93f1-07d6359a92e9",
"district_": "2",
"_feature_id": "2",
"_feature_id_string": "Police_Districts.2",
"dist_num": "2",
"div_code": "NEPD",
"phone": "686-3020",
"incidents": 32340
}
}
,
{
"type": "Feature",
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
-75.1972382872565,
39.9294288475177
],
[
-75.1969248893574,
39.9291749499585
],
[
-75.1966534158686,
39.9293232425744
],
]
]
]
},
"properties": {
"area": "",
"location": "24th St. & Wolf St.",
"perimeter": "81903.64182498",
"dist_numc": "01",
"sum_area": "",
"area_sqmi": "216350124.153",
"district_i": "",
"objectid": "321",
"globalid": "c040618c-ac93-4b22-b174-0ea08e0f805d",
"district_": "1",
"_feature_id": "1",
"_feature_id_string": "Police_Districts.1",
"dist_num": "1",
"div_code": "SPD",
"phone": "686-3010",
"incidents": 11553
}
},
{
"type": "Feature",
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
-75.1343640909741,
39.9529315410666
],
[
-75.1352375679666,
39.9506957263754
],
[
-75.1352409996735,
39.9506869425429
]
]
]
]
},
"properties": {
"area": "",
"location": "11th St. & Winter St.",
"perimeter": "34655.32085552",
"dist_numc": "06",
"sum_area": "",
"area_sqmi": "69279267.8986235",
"district_i": "",
"objectid": "325",
"globalid": "e0afa680-ecd3-470e-b0f8-59b70d4f72b5",
"district_": "6",
"_feature_id": "5",
"_feature_id_string": "Police_Districts.5",
"dist_num": "6",
"div_code": "CPD",
"phone": "686-3060",
"incidents": 23428
}
}
]
};
console.log("Before sorting");
console.log(data.features[0].properties.incidents);
console.log(data.features[1].properties.incidents);
console.log(data.features[2].properties.incidents);
data.features.sort(function (a, b) {
if (a.properties.incidents < b.properties.incidents)
return -1;
else if (a.properties.incidents > b.properties.incidents)
return 1;
});
console.log("After sorting");
console.log(data.features[0].properties.incidents);
console.log(data.features[1].properties.incidents);
console.log(data.features[2].properties.incidents);

Reshaping Flat JSON Structures with JavaScript

Currently, I have data in a flat JSON format. We need to convert it to a particular structure.
[
{
"Region":"WEST",
"District":"PACIFIC",
"timestamp":"2018-12-28T00:00:00.000Z",
"Penetration":374
},
{
"Region":"WEST",
"District":"MOUNTAIN",
"timestamp":"2018-12-28T00:00:00.000Z",
"Penetration":427
},
{
"Region":"SOUTH",
"District":"SOUTH WEST",
"timestamp":"2018-12-28T00:00:00.000Z",
"Penetration":422
},
{
"Region":"SOUTH",
"District":"SOUTH EAST",
"timestamp":"2018-12-28T00:00:00.000Z",
"Penetration":410
}
]
It should be as such. Also a constant "version": "v1" needs to be added to each object. The flattened result-set can be dynamic. So apart from timestamp key whatever key-value pair are present shall be pulled inside event object.
[
{
"version": "v1",
"timestamp": "2018-12-28T00:00:00.000Z",
"event": {
"Penetration":374,
"Region": "WEST",
"District": "PACIFIC"
}
},
{
"version": "v1",
"timestamp": "2018-12-28T00:00:00.000Z",
"event": {
"Penetration":427,
"Region": "WEST",
"District": "MOUNTAIN"
}
},
{
"version": "v1",
"timestamp": "2018-12-28T00:00:00.000Z",
"event": {
"Penetration":422,
"Region": "SOUTH",
"District": "SOUTH WEST"
}
}
{
"version": "v1",
"timestamp": "2018-12-28T00:00:00.000Z",
"event": {
"Penetration":410
"Region": "SOUTH",
"District": "SOUTH EAST"
}
}
]
You can simply make use of map method:
var data=[ { "Region":"WEST", "District":"PACIFIC", "timestamp":"2018-12-28T00:00:00.000Z", "Penetration":374 }, { "Region":"WEST", "District":"MOUNTAIN", "timestamp":"2018-12-28T00:00:00.000Z", "Penetration":427 }, { "Region":"SOUTH", "District":"SOUTH WEST", "timestamp":"2018-12-28T00:00:00.000Z", "Penetration":422 }, { "Region":"SOUTH", "District":"SOUTH EAST", "timestamp":"2018-12-28T00:00:00.000Z", "Penetration":410 }];
var result = data.map(({timestamp, ...events})=>({version:'v1',timestamp, events}));
console.log(result);

Delete a KEY Name in javascript

I have something like this.
"data": {
"abcd": [
{
"abc": {
"fr": "India",
"to": "Moon",
}
},
{
"abc": {
"fr": "Mars",
"to": "Jupiter",
}
}
],
"distance": 1234,
}
But I want to convert to something like this
"data": {
"abcd": [
{
"fr": "India",
"to": "Moon",
},
{
"fr": "Mars",
"to": "Jupiter",
}
],
"distance": 1234,
}
I want to brign the details inside the abc object and make them as an unnamed object inside the abcd array of objects.
Please help out with this.
A simple reduce() will suffice
let obj = {
"data": {
"abcd": [{
"abc": {
"fr": "India",
"to": "Moon",
}
},
{
"abc": {
"fr": "Mars",
"to": "Jupiter",
}
}
],
"distance": 1234,
}
};
obj.data.abcd = obj.data.abcd.reduce((a, b) => a.concat(b.abc), []);
console.log(obj);
Use Array#map to iterate the array and return the contents of the abc key of each object. Assign the results to obj.data.abcd:
const obj = {"data":{"abcd":[{"abc":{"fr":"India","to":"Moon"}},{"abc":{"fr":"Mars","to":"Jupiter"}}],"distance":1234}};
obj.data.abcd = obj.data.abcd.map((o) => o.abc);
console.log(obj);

Iterate through JSON from MapQuest API

I'm parsing JSON response from the MapQuest API. I need all of the 'narratives' from the 'legs' node under 'maneuvers' (legs-> maneuvers -> get all narratives), but I cannot figure it out.
I can get most of the values like so:
$(function(){
var mq = jQuery.parseJSON(jsonResponse);
$("#fuel").html(mq.renderMatrixResults[0].route.fuelUsed);
$("#rtime").html(mq.renderMatrixResults[0].route.realTime);
});
Part of JSON response:
{
"renderMatrixResults": [
{
"route": {
"hasTollRoad": true,
"computedWaypoints": [
],
"fuelUsed": 2.24,
"hasUnpaved": false,
"hasHighway": true,
"realTime": 5556,
"boundingBox": {
"ul": {
"lng": -74.240074,
"lat": 40.662548
},
"lr": {
"lng": -74.132072,
"lat": 40.573451
}
},
"distance": 38.998,
"time": 5523,
"hasSeasonalClosure": false,
"locations": [
{
"latLng": {
"lng": -74.18862,
"lat": 40.609712
},
"adminArea4": "Brooklyn",
"adminArea5Type": "City",
"adminArea4Type": "County",
"adminArea5": "Brooklyn",
"street": "1234 Test Lane",
"adminArea1": "US",
"adminArea3": "NY",
"type": "s",
"displayLatLng": {
"lng": -74.188621,
"lat": 40.60971
},
"linkId": 33589148,
"postalCode": "10001-6992",
"sideOfStreet": "L",
"dragPoint": false,
"adminArea1Type": "Country",
"geocodeQuality": "POINT",
"geocodeQualityCode": "P1AAA",
"adminArea3Type": "State"
},
{
"latLng": {
"lng": -74.194858,
"lat": 40.601623
},
"adminArea4": "Brooklyn",
"adminArea5Type": "City",
"adminArea4Type": "County",
"adminArea5": "Brooklyn",
"street": "5678 Example Street",
"adminArea1": "US",
"adminArea3": "NY",
"type": "s",
"displayLatLng": {
"lng": -74.194854,
"lat": 40.601623
},
"linkId": 33361764,
"postalCode": "10001-5483",
"sideOfStreet": "R",
"dragPoint": false,
"adminArea1Type": "Country",
"geocodeQuality": "POINT",
"geocodeQualityCode": "P1AAA",
"adminArea3Type": "State"
}
],
"hasCountryCross": false,
"legs": [
{
"hasTollRoad": false,
"index": 0,
"roadGradeStrategy": [
[
]
],
"hasHighway": false,
"hasUnpaved": false,
"distance": 0.882,
"time": 145,
"origIndex": 1,
"hasSeasonalClosure": false,
"origNarrative": "Go west on some road",
"hasCountryCross": false,
"formattedTime": "00:02:25",
"destNarrative": "Proceed to 789 GIRAFFE STREET",
"destIndex": 1,
"maneuvers": [
{
"signs": [
],
"index": 0,
"maneuverNotes": [
],
"direction": 4,
"narrative": "Start out going south on Elephant Avenue.",
"iconUrl": "https://content.mapquest.com/mqsite/turnsigns/icon-dirs-start_sm.gif",
"distance": 0.57,
"time": 79,
"linkIds": [
],
"streets": [
"Elephant Avenue"
],
"attributes": 0,
"transportMode": "AUTO",
"formattedTime": "00:01:19",
"directionName": "South",
"mapUrl": "https://www.mapquestapi.com/staticmap/v4/getmap?key=Fmjtd|luur20uanq,b0=o5-9ayxdw&type=map&size=225,160&pois=purple-1,40.60971,-74.188621,0,0|purple-2,40.602351999999996,-74.189582,0,0|�er=40.606031,-74.18910149999999&zoom=10&rand=-1416511403&session=53c1fb45-030d-0004-02b7-16b5-00163e4c0d3f",
"startPoint": {
"lng": -74.188621,
"lat": 40.60971
},
"turnType": 2
},
{
"signs": [
],
"index": 1,
"maneuverNotes": [
],
"direction": 7,
"narrative": "Turn right onto Tiger Blvd.",
"iconUrl": "https://content.mapquest.com/mqsite/turnsigns/rs_right_sm.gif",
"distance": 0.269,
"time": 56,
"linkIds": [
],
"streets": [
"Tiger Blvd"
],
"attributes": 0,
"transportMode": "AUTO",
"formattedTime": "00:00:56",
"directionName": "West",
"mapUrl": "https://www.mapquestapi.com/staticmap/v4/getmap?key=Fmjtd|luur20uanq,b0=o5-9ayxdw&type=map&size=225,160&pois=purple-2,40.602351999999996,-74.189582,0,0|purple-3,40.601127,-74.194366,0,0|�er=40.601739499999994,-74.191974&zoom=12&rand=-1416511403&session=53c1fb45-030d-0004-02b7-16b5-00163e4c0d3f",
"startPoint": {
"lng": -74.189582,
"lat": 40.602352
},
"turnType": 2
}
Haven't tested it but here is the idea. You can use a function that will traverse object tree and collect items specified by a path.
function getPath(path, obj) {
var name, value;
path = path instanceof Array ? path: path.split('.'); //convert path to array
name = path.shift(); //get the first name
value = obj[name]; //extract value
if(!path.length || value == null) { //last name or value is null or undefined
return value;
}
if(value instanceof Array) { //if value is array - concat
return [].concat.apply([], value.map(function(item){
return getPath(path.slice(0), item);
}));
}
return getPath(path, value); //else go deeper
}
Usage:
var narratives
= getPath('renderMatrixResults.route.legs.maneuvers.narrative', mq);
I believe the path is correct.

Categories