What is wrong in sort function, need improvements also - javascript

I hava a json object have some records, and I need to sort the object,
code:
var data = [
{
"MRData": {
"StandingsTable": {
"StandingsLists": [
{
"season": "2014",
"round": "5",
"DriverStandings": [
{
"position": "2",
"positionText": "1",
"points": "100",
"wins": "4",
"Driver": {...},
"Constructors": [...]
},
{
"position": "1",
"positionText": "2",
"points": "97",
"wins": "1",
"Driver": {...},
"Constructors": [...]
}
]
}
]
}
}
}
];
//What is Wrong in This function
function sortObj(obj, nextObj){
console.log(obj.position);
console.log(nextObj.position);
if(obj.position < nextObj.position){
return obj;
}else{
return nextObj;
}
}
var driverObjects = data[0].MRData.StandingsTable.StandingsLists[0].DriverStandings;
console.log(driverObjects);
var sortedData = driverObjects.sort(sortObj); //Do I need to use any other functions //like filter, map ?
console.log(sortedData);
Fiddle
Have a look at the console, to use the output, I was excepting the output like
[Object { position="1", positionText="1", points="100", more...}, Object { position="2", positionText="2", points="97", more...}]
But it is displaying same as passed function.
please correct the function mistakes.
Give me an optimized or more standard code implementation

sortObj() should return either positive value or negative value or 0
You can do like this..
function sortObj(obj, nextObj){
console.log(obj.position);
console.log(nextObj.position);
return nextObj.position-obj.position
}

The callback function for the sort method should return -1 (when the second parameter is greater), 0 (when both parameters are equal) or 1 (when the first parameter is greater)
Array.prototype.sort()
so you need this sort function:
function sortObj(obj, nextObj){
return obj.position - nextObj.position;
}

Related

Loop through array of nested objects to check empty string es6

I have an array of nested objects:
const array =[
{
"id": 1,
"time": {
"timezone": "2021-09-22T05:36:22.484Z"
"city": "Perth"
"country:: "Australia
"date": "2021/10/10"
}
},
{
​"id": 2,
​"time": {
"timezone": ​"2021-10-22T03:25:26.484Z"
"city": ""
"country: "Americas"
"date": "2021/10/10"
}
},
{
​"id": 3,
​"time": {
"timezone": ​"2021-09-27T02:43:26.564Z"
"city": ""
"country: ""
"date": "2021/10/10"
}
}];
I want to check each value in the time object to see if there exists an empty string without having to have multiple || statements.
What I have tried using lodash:
if(array.find((k)=> _.isEmpty(k.timezone)) || array.find((k)=> _.isEmpty(k.city)) || array.find((k)=> _.isEmpty(k.country)) || array.find((k)=> _.isEmpty(k.date))) {
//do something
} else {
//do something else
}
This seems to do the trick but trying to find a succinct and cleaner way to do this as there could be more values in the time object, preferably in es6.
Check if .some of the Object.values of any of the time subobjects includes the empty string.
if (array.some(
k => Object.values(k.time).includes('')
)) {
// do something
} else {
// do something else
}

Geolib and getPreciseLocation through an Array

I have an array and I need to order the data of it by the distance of a specific point.
Knowing that .sort() won't work since I'm dealing with coordinates, I've been using a library called Geolib which has a function called getPreciseLocation() which is exactly what I need, but it doesn't seem to work while iterating through an array.
Here is the array containing the data I will be using.
Data:
[
{
"id": "1",
"Point": "27.1597268, 40.6646601"
},
{
"id": "2",
"Point": "11.1640393, 49.648713"
},
{
"id": "3",
"Point": "26.1539253, 42.6599287"
},
{
"id": "4",
"Point": "21.1597268, 44.6646601"
},
{
"id": "5",
"Point": "10.1640393, 43.648713"
},
{
"id": "6",
"Point": "26.1539253, 61.6599287"
}
]
The code I've been trying to use to iterate through the array.
let DistancesFromUserLocation = [];
this.state.Data.forEach(item => {
DistancesFromUserLocation.push(geolib.getPreciseDistance({latitude: 30.1891168, longitude: 11.6226982}, item.Point))
})
As a disclaimer: I only need to get to receive the distance of each array object to a new array.
I've tried and researched many things and get around the solution, but just about thinking that I am getting to the solution, something would go wrong.
You need to push the generated distance each iteration to DistancesFromUserLocation array.
let DistancesFromUserLocation = [];
this.state.Data.forEach(item => {
// push each distance to `DistancesFromUserLocation`
DistancesFromUserLocation.push(
geolib.getPreciseDistance(
{latitude: 30.1891168, longitude: 11.6226982},
item.Point
);
)
})
Only then you can use the Array.sort().
console.log(DistancesFromUserLocation.sort());
EDIT:
Check my working example here at codesandbox.

How can I combine this data into one Object?

This one is a tricky one.
So, lets say I have two JS objects that are fetched via REST call, via two callbacks.
So, we have:
call1() - POST method - parsed JSON to JS object, route: {{url}}/data
call1.json:
"data": [
{
"id": "1",
"volume:" "2000"
},
{
"id": "2",
"volume:" "3000"
},
{
"id": "3",
"volume:" "4000"
},
{
"id": "4",
"volume:" "5000"
}
];
call2(req.body.id) - GET method - parsed JSON to JS object, route: {{url}}/data/:id
For example, if I pass req.body.id as = 1 got from the first response, it will open data for that id. So:
return call2(2) will return the data from this JSON: call2.json:
"data": [
{
"id": "1",
"add_data": "important string",
"add_data_2": "important string two"
},
];
The bottom line is, when doing the {{url}}/data route call - call() I need to serve all the data from {{url}}/data/:id routes, and bind them to the correct id. So, for example, the scenario I am trying to achieve is this:
Inside call(): get call1.json: data, do as many call2(req.body.id) calls as there are ids in the first object and then combine add_data and add_data_two values in the first object. So for example the final object would look like this.
console.log(response)
"data": [
{
"id": "1",
"volume:" "2000",
"add_data": "important string",
"add_data_2": "important string two"
},
{
"id": "2",
"volume:" "3000",
"add_data": "important string",
"add_data_2": "important string two"
},
{
"id": "3",
"volume:" "4000",
"add_data": "important string",
"add_data_2": "important string two"
},
{
"id": "4",
"volume:" "5000",
"add_data": "important string",
"add_data_2": "important string two"
}
];
This is what I have tried so far:
async get_data(req) {
try {
const objFirst = await call1(); //gets data
let objTwo = '';
for (let i = 0; i < objFirst.data.length; i++) {
objTwo = await call2({id: objFirst.data[i].id}) //gets data
}
return objFirst;
} catch(err) {
console.log("Error: ", err)
}
}
But it does not work. How can I get all data, and make as many as call2(id) as there are ids and combine that all in one object? Basically, I need to repeat this callback -> call2(id) as many ids we receive in call1().
Thanks, sorry if it looks like a mess.
You can use the map function and spread operator for this. Something like below.
Call2 function just simulates what an endpoint would return, but you get the idea.
var data = [
{
id: 1,
add_data: "1111"
},
{
id: 2,
add_data: "2222"
}
];
var data2 = [
{
id: 1,
volume: "bla"
},
{
id: 2,
volume: "bla"
}
];
function call2(id) {
return data2.filter(x => x.id == id)[0];
}
var result = data.map(x => {
var response = call2(x.id);
return {
...x,
...response
}
})
console.dir(result[0]);
The speed of your solution (loop through an array and doing http calls to get more data is really slow). If you have a lot of these functions that needs to combine data from different datasources, and depending on your project size, i would look into either RXJS or GraphQL (If you really need performance). RXJS have great functions to merge, combine, map etc data.
RXJS
GraphQL

Parsing JSON array created from PHP array

{
"3": {
"id": "3",
"ocena_ocena": "2",
"ocena_profesor": "\u041c\u0430\u0440\u043a\u043e \u041c\u0430\u0440\u043a\u043e\u0432\u0438\u045b",
"ocena_napomena": "",
"ocena_datum": "31.12.2015."
},
"1": {
"id": "1",
"ocena_ocena": "5",
"ocena_profesor": "\u041c\u0430\u0440\u043a\u043e \u041c\u0430\u0440\u043a\u043e\u0432\u0438\u045b",
"ocena_napomena": "",
"ocena_datum": "22.12.2015."
}
}
I am using ajax to get this JSON. I tried parsing it like this:
request.done(function(response) {
alert(response.ocena_ocena);
});
Could someone please help me with this?
I also need to know how can I do a foreach statement with json?
Since your JSON represents a JavaScript object, you should include the attribute name (if we consider JavaScript object to be a map, then, we need to use the key).
Try
response["1"].ocena_ocena
or
response["3"].ocena_ocena
Since you are returning a JSON object from server instead of an array, to iterate over its properties, you could do
for (var i in response) {
console.log(response[i].ocena_ocena);
}
or
Object.keys(response).forEach(function f(e) {console.log(response[e].ocena_ocena)})
If you could modify your server side code to return JSON that looks like this,
[
{
"id": "3",
"ocena_ocena": "2",
...
},
{
"id": "1",
"ocena_ocena": "5",
...
}
]
then you could iterate over it more easily
response.forEach(function f(e) {console.log(e.ocena_ocena)})

JavaScript Remove Object From Array Based on Child Property

Using vanilla JavaScript (supported by the latest version of Chrome, don't worry about IE) and/or lodash/underscore but no jQuery how can I take this array:
[
{
"id": 1,
"places": {
"city": "boston"
}
},
{
"id": 2,
"places": {
"city": "new york"
}
}
]
...and remove the entire object that has a city of "boston":
[
{
"id": 2,
"places": {
"city": "new york"
}
}
]
Please keep in mind this array could have dozens of entries. Thank you!
http://plnkr.co/edit/JW3zd6A7OcmihM4CTh1D?p=preview
One of the ways you can do this is by using filter. For example:
var dataWithoutBoston = data.filter(function (el) {
return el.places.city !== "boston";
});
And to make it reusable, you can have a function like this:
function removeFromCity(data, name) {
var result = data.filter(function (el) {
return el.places.city !== name;
});
return result;
};

Categories