How to group an array of objects into array - javascript

I need help regarding my problem as I couldn't wrap around my head with this problem.
so my JSON data looks like this.
let items = [
{
"cargo": {
"name": "Horse 1",
"picture": "https://images.unsplash.com/photo-1553284965-5dd8352ff1bd?ixlib=rb-1.2.1&w=1000&q=80"
},
"pickup_location": {
"address": {
"longitude": 120.96667,
"latitude": 14.65,
"name": "....",
"full_address": "...."
},
},
"dropoff_location": {
"address": {
"longitude": 120.86667,
"latitude": 14.78333,
"name": "....",
"full_address": "...."
}
}
},
{
"cargo": {
"name": "Horse 5",
"picture": "https://i.ytimg.com/vi/qWeQrv1Foqo/maxresdefault.jpg"
},
"pickup_location": {
"address": {
"longitude": 120.96667,
"latitude": 14.65,
"name": "....",
"full_address": "...."
}
},
"dropoff_location": {
"address": {
"longitude": 120.86667,
"latitude": 14.78333,
"name": "....",
"full_address": "...."
}
}
}
]
and I want to group the data by using the latitude and longitude of the pickup and dropoff locations and output them into something like this.
[
{
"cargo": [
{
"name": "Horse 1",
"picture": "https://images.unsplash.com/photo-1553284965-5dd8352ff1bd?ixlib=rb-1.2.1&w=1000&q=80"
},
{
"name": "Horse 5",
"picture": "htthttps://i.ytimg.com/vi/qWeQrv1Foqo/maxresdefault.jpg"
},
]
"pickup_location": {
"address": {
"longitude": 120.96667,
"latitude": 14.65,
"name": "....",
"full_address": "...."
}
},
"dropoff_location": {
"address": {
"longitude": 120.86667,
"latitude": 14.78333,
"name": "....",
"full_address": "...."
}
}
}
]
I've attempted writing a reduce function but couldn't wrap my head around it. so please help me.
any answers are appreciated.
Thank you.

This will group similar item with unique details:
itemsGroup = {};
for(var item of items) {
for(var key in item) {
if(!itemsGroup[key]) {
itemsGroup[key] = [];
itemsGroup[key].push(item[key]);
}
else {
var detailExists = itemsGroup[key].find(detail => JSON.stringify(detail) == JSON.stringify(item[key]));
if(!detailExists) {
itemsGroup[key].push(item[key]);
}
}
}
}
console.log(itemsGroup);

I wouldn't expect pickup and dropoff to match every time.
It's probably best to create two objects to track them. I used a combination of lat+long for the key to keep it simple.
pickUps = {};
dropOffs = {};
items.forEach(function (item) {
pickUpLoc = [
item.pickup_location.address.longitude,
item.pickup_location.address.latitude,
].join(":");
dropOffLoc = [
item.dropoff_location.address.longitude,
item.dropoff_location.address.latitude,
].join(":");
if (pickUps[pickUpLoc] != undefined) {
pickUps[pickUpLoc].cargo.push(item.cargo);
} else {
pickUps[pickUpLoc] = {
cargo: [item.cargo],
address: item.pickup_location.address,
};
}
if (dropOffs[dropOffLoc] != undefined) {
dropOffs[dropOffLoc].cargo.push(item.cargo);
} else {
dropOffs[dropOffLoc] = {
cargo: [item.cargo],
address: item.dropoff_location.address,
};
}
});

Related

How to get common value in Object Array in JavaScript

const data = {
"games": [
{
"id": "828de9122149499183df39c6ae2dd3ab",
"developer_id": "885911",
"game_name": "Minecraft",
"first_release": "2011-18-11",
"website": "https://www.minecraft.net/en-us"
},
{
"id": "61ee6f196c58afc9c1f78831",
"developer_id": "810637",
"game_name": "Fortnite",
"first_release": "2017-21-07",
"website": "https://www.epicgames.com/fortnite/en-US/home"
},
],
"developers": [
{
"id": "885911",
"name": "Mojang Studios",
"country": "US",
"website": "http://www.mojang.com",
},
{
"id": "750245",
"name": "God of War",
"country": "SE",
"website": "https://sms.playstation.com",
},
] };
I have json data like this. I want to display data like if developer_id = 885911(from games array) then print id(from developers array) and if the both are same then I want to print the name.(Mojang studios) and so on like games website etc. How can I do that?
This sample code will show you the developer of each game, if it's found:
const data = {
"games": [
{
"id": "828de9122149499183df39c6ae2dd3ab",
"developer_id": "885911",
"game_name": "Minecraft",
"first_release": "2011-18-11",
"website": "https://www.minecraft.net/en-us"
},
{
"id": "61ee6f196c58afc9c1f78831",
"developer_id": "810637",
"game_name": "Fortnite",
"first_release": "2017-21-07",
"website": "https://www.epicgames.com/fortnite/en-US/home"
},
],
"developers": [
{
"id": "885911",
"name": "Mojang Studios",
"country": "US",
"website": "http://www.mojang.com",
},
{
"id": "750245",
"name": "God of War",
"country": "SE",
"website": "https://sms.playstation.com",
},
] };
const gameDevelopers = data.games.map(g => ({
game: g.game_name,
developer: data.developers.find(d => d.id === g.developer_id)?.name || "No matching developer found"
}));
console.log(gameDevelopers)
What did you exactly need? i don't understand . But you can get value Mojang Studios
console.log(data.developers[0].name)
If you need all developer id then you can use
console.log(data.developers.map(data=>{
console.log(data.id)
}))
If you need the id where name is Mojang Studios
console.log(data.developers.map(data=>{
if(data.name == "Mojang Studios"){
console.log(data.id)
}
}))

How to replace JSON Object Array with a new array [duplicate]

This question already has answers here:
Find object by id in an array of JavaScript objects
(36 answers)
Closed 2 years ago.
I want to loop through the allData and search if the id matches 12345,
I want to remove the Offer Object and insert the newOffer Object
$(document).ready(function () {
var newOfferToInsert = {
"id": "12345",
"name": "ssfd Offer"
}
var idToSearch = '12345'
var allData = [{
"id": {
"Street": "555 92nd St S",
"id": "12345"
},
"Offer": {
"id": "12345"
}
}, {
"id": {
"Street": "666 DFTYY",
"id": "345"
},
"Offer": {
"id": "345"
}
}];
});
https://jsfiddle.net/9avwsm1p/
You can do it like this:
allData.forEach(function(cartObj) {
if(cartObj.id.id === idToSearch){
cartObj.Offer = newOfferToInsert;
}
});
const newOfferToInsert = {
"id": "12345",
"name": "ssfd Offer"
}
const idToSearch = '12345'
const allData = [{
"id": {
"Street": "555 92nd St S",
"id": "12345"
},
"Offer": {
"id": "12345"
}
}, {
"id": {
"Street": "666 DFTYY",
"id": "345"
},
"Offer": {
"id": "345"
}
}];
console.log(replaceOffer(allData, idToSearch, newOfferToInsert))
function replaceOffer(allData, idToSearch, newOfferToInsert) {
return allData.map(element => {
if (element.Offer.id === idToSearch) {
element.Offer = newOfferToInsert
}
return element
})
}
var newOfferToInsert = {
"id": "12345",
"name": "ssfd Offer"
}
var idToSearch = '12345'
var allData = [{
"id": {
"Street": "555 92nd St S",
"id": "12345"
},
"Offer": {
"id": "12345"
}
}, {
"id": {
"Street": "666 DFTYY",
"id": "345"
},
"Offer": {
"id": "345"
}
}];
allData.forEach((obj)=>{
if(obj.Offer.id===idToSearch)
{
obj.Offer=newOfferToInsert
}
})
console.log(allData)

Filtering array of objects with a search term gets "TypeError: includes is not a function"

I don't seem to understand JavaScript enough to get why this doesn't work:
let sample = [
{
"id":90,
"name":"Fort McMurray Airport",
"city":"Fort Mcmurray",
},
{
"id":273,
"name":"Murtala Muhammed International Airport",
"city":"Lagos",
},
{
"id":1227,
"name":"San Javier Airport",
"city":"Murcia"
},
{
"id":1235,
"name":"Alcantarilla Air Base",
"city":"Murcia",
},
{
"id":1275,
"name":"Muret-Lherm Airport",
"city":"La Rochelle",
},
]
let airports = sample.filter(
function(obje) {
return Object.keys(obje).some(
function(key) {
return obje[key].includes("Murc");
}
);
}
);
I keep getting a "TypeError: obje[key].includes is not a function"
BTW, this is content from an axios call
Thanks in advance.
I solved it like so:
let query = "Murc";
let new_airports = sample.filter(sample => (sample.name.includes(query) || sample.city.includes(query) ) );
I was letting the code fly over my head. However, is there a better way?
TypeError: obje[key].includes is not a function
This error caused by id types
in your sample data, id is Number but includes() is for string only.
let sample = [{
"id": 90,
"name": "Fort McMurray Airport",
"city": "Fort Mcmurray",
},
{
"id": 273,
"name": "Murtala Muhammed International Airport",
"city": "Lagos",
},
{
"id": 1227,
"name": "San Javier Airport",
"city": "Murcia"
},
{
"id": 1235,
"name": "Alcantarilla Air Base",
"city": "Murcia",
},
{
"id": 1275,
"name": "Muret-Lherm Airport",
"city": "La Rochelle",
},
]
const res = sample.filter((item, index) => {
return Object.keys(item).some((key) => {
return item[key].toString().includes('Murc')
});
});
console.log(res);
includes might not work for a string, try indexOf instead.
Do something like this : return obje[key].indexOf("Murc") > -1;

How to avoid duplicate records adding inside angular for each loop?

The below directive code is forming an JSON dynamically. I have to form a JSON without dupicate object names.
Angular Code:
bosAppModule.directive('layoutTableCellControlLabelRender',function($compile,$rootScope){
var layoutTableCellControlLabelObj={};
var soJSON = {
entityInfo: {
entity: "",
tenantId: "",
timeStamp: new Date().toJSON().toString()
},
collections: {
}
};
var myobj={};
linkFnTableCellControlLabel=function(scope, element, attributes, controllerCtrl) {
scope.labelData="NO DATA";
angular.forEach(scope.pageObject.collections.objectattribute.rowset, function (value, index) {
if(value.objectattributeid==scope.attributeId){
scope.labelData=value.objectattributelabelname;
scope.attributeName=value.objectattributename;
//$rootScope.$broadcast("NEW_EVENT", scope.attributeName);
angular.forEach(scope.pageObject.collections.object.rowset, function (value2, index2) {
if(value2.tenantobjectid==value.objectattributeobjectid){
scope.objectname=value2.tenantobjectname;
if(!soJSON.collections[scope.objectname]) {
soJSON.collections[scope.objectname]={
"meta": {
"parentreference": "***",
"pkname": "***",
"fkname": "***"
},
"rowset": [],
"rowfilter": []
};
}
}
});
myobj[scope.attributeName]="test";
soJSON.collections[scope.objectname].rowset.push(myobj);
}
});
console.log(JSON.stringify(soJSON));
};
layoutTableCellControlLabelObj.scope={attributeId:'=',layoutData:'=',pageObject:'='};
layoutTableCellControlLabelObj.restrict='AE';
layoutTableCellControlLabelObj.replace='true';
layoutTableCellControlLabelObj.template="<div class='col-xs-12 col-sm-12 col-md-6 col-lg-6' attribute-name={{attributeName}} attribute-id='tablecellcontrol.layouttablecellcontrolbindingobjectattributeid' " +
"layout-data='layoutData' page-object='pageObject'><label class='k-label pull-right'>{{labelData}}</label></div>";
layoutTableCellControlLabelObj.link = linkFnTableCellControlLabel;
return layoutTableCellControlLabelObj;
});
Using aboeve code i am getting the JSON. In this JSON inside rowset records are duplicated because of loop. But i'm bit confused on this. I need avoid it. It should create only one time.
Anyone please help me to achieve this. If you need more details on this. let me know.
JSON
{
"entityInfo": {
"entity": "",
"tenantId": "",
"timeStamp": "2016-04-07T07:25:49.711Z"
},
"collections": {
"Customer29Jan16": {
"meta": {
"parentreference": "***",
"pkname": "***",
"fkname": "***"
},
"rowset": [
{
"CuId": "test",
"Name": "test",
"Quantity": "test",
"Rate": "test",
"Amount": "test"
},
{
"CuId": "test",
"Name": "test",
"Quantity": "test",
"Rate": "test",
"Amount": "test"
},
{
"CuId": "test",
"Name": "test",
"Quantity": "test",
"Rate": "test",
"Amount": "test"
},
{
"CuId": "test",
"Name": "test",
"Quantity": "test",
"Rate": "test",
"Amount": "test"
},
{
"CuId": "test",
"Name": "test",
"Quantity": "test",
"Rate": "test",
"Amount": "test"
}
],
"rowfilter": []
}
}
}
I don't know if it's always the same json but you can probably use uniqby from lodash on your rowset array.
_.uniqBy(json.collections.Customer29Jan16.rowset, function (e) {
return e.CuId;
});
Demo
EDIT
If you have several customers, you can loop over a customer array :
arrayOfCustomers = (Object.keys(json.collections));
for(var i = 0 ; i < arrayOfCustomers.length; i++){
json.collections[arrayOfCustomers[i]].rowset = _.uniqBy(json.collections[arrayOfCustomers[i]].rowset, function (e) {
return e.CuId;
});
}
https://jsfiddle.net/kq9gtdr0/23/

Covert JSON objects inside json objects into a JSON Array in Javascript

Hello I have the following JSON structure and I try to make an array of each object inside each object but there is a way to convert it without iterating each element and get every element.
Or maybe using a Javascript function to get object inside objects and convert to an array?
{
"ES": {
"130": {
"code": "A Coruсa",
"name": "A Coruña"
},
"131": {
"code": "Alava",
"name": "Alava"
},
"...": {
"code": "...",
"name": "..."
}
},
"CH": {
"104": {
"code": "AG",
"name": "Aargau"
},
"...": {
"code": "...",
"name": "..."
}
},
"...": {
"...": {
"code": "...",
"name": "..."
}
}
}
This is what I am looking for:
[
{
"code": "A Coruсa",
"name": "A Coruña"
},
{
"code": "Alava",
"name": "Alava"
},
{
"code": "...",
"name": "..."
},
{
"code": "AG",
"name": "Aargau"
},
{
"code": "...",
"name": "..."
},
{
"code": "...",
"name": "..."
}
]
Thanks for your help, I accept any recommendations.
You can use Object.keys(), Array.prototype.reduce() and Array.prototype.map() for iterating over the properties and for assembling the array.
var obj = { "ES": { "130": { "code": "A Coruсa", "name": "A Coruña" }, "131": { "code": "Alava", "name": "Alava" }, }, "CH": { "104": { "code": "AG", "name": "Aargau" } } },
result = Object.keys(obj).reduce(function (r, k) {
return r.concat(Object.keys(obj[k]).map(function (kk) {
return obj[k][kk];
}));
}, []);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
I have created a fiddle to convert the data. look at it
https://jsbin.com/suzice/edit?js,output
var data = {
"ES": {
"130": {
"code": "A Coruсa",
"name": "A Coruña"
},
"131": {
"code": "Alava",
"name": "Alava"
},
"...": {
"code": "...",
"name": "..."
}
},
"CH": {
"104": {
"code": "AG",
"name": "Aargau"
},
"...": {
"code": "...",
"name": "..."
}
}
};
var list = [];
Object.keys(data).forEach(function(key){
Object.keys(data[key]).forEach(function(sub_key){
list.push(data[key][sub_key]);
});
console.log(list);
});

Categories