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

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)

Related

How to group an array of objects into array

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,
};
}
});

Iterate and group the objects using map function

Check for the decimal id and group them accordingly.
Below are the sample and recommended JSON's
Sample JSON
{
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
}
Would like to iterate and Re-structure the above JSON into below recommended format.
Logic: Should check the id(with and without decimals) and group them based on the number.
For Example:
1, 1.1, 1.2.3, 1.4.5 => data1: [{id: 1},{id: 1.1}....]
2, 2.3, 2.3.4 => data2: [{id: 2},{id: 2.3}....]
3, 3.1 => data3: [{id: 3},{id: 3.1}]
Recommended JSON
{
"results": [
{
"data1": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
}
]
},
{
"data2": [
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
}
]
},
{
"data3": [
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
}
]
},
{
"data4": [
{
"name": "Download",
"id": "4.2"
}
]
}
]
}
I have tried the below solution but it doesn't group the object
var formatedJSON = [];
results.map(function(d,i) {
formatedJSON.push({
[data+i]: d
})
});
Thanks in advance.
You can use reduce like this. The idea is to create a key-value pair for each data1, data2 etc so that values in this object are the values you need in the final array. Then use Object.values to get those as an array.
const sampleJson = {"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]}
const grouped = sampleJson.results.reduce((a, v) => {
const key = `data${parseInt(v.id)}`;
(a[key] = a[key] || {[key]: []})[key].push(v);
return a;
},{});
console.log({results: Object.values(grouped)})
One liner / Code-golf:
let s={"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]},k;
console.log({results:Object.values(s.results.reduce((a,v)=>(k=`data${parseInt(v.id)}`,(a[k] = a[k]||{[k]:[]})[k].push(v),a),{}))})
Here you go:
var data = {
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
};
let newSet = new Set();
data.results.forEach(e => {
let key = e.id.substring(0, e.id.indexOf('.'));
console.log(key);
if (newSet.has(key) == false) {
newSet.add(key);
newSet[key] = [];
}
newSet[key].push(e.id);
});
console.log(newSet);
Here's how you'd do it:
var data = {
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
};
var newData = {
"results": {}
};
data.results.forEach(item => {
var num = item.id.slice(0, 1);
if (newData.results["data" + num]) {
newData.results["data" + num].push(item);
} else {
newData.results["data" + num] = [item];
}
})
data = newData;
console.log(data);
What this does is it iterates through each item in results, gets the number at the front of this item's id, and checks if an array of the name data-{num} exists. If the array exists, it's pushed. If it doesn't exist, it's created with the item.
let input = getInput();
let output = input.reduce((acc, curr)=>{
let {id} = curr;
let majorVersion = 'name' + id.split('.')[0];
if(!acc[majorVersion]) acc[majorVersion]= [];
acc[majorVersion].push(curr);
return acc;
},{})
console.log(output)
function getInput(){
return [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
}
One solution with RegEx for finer control as it would differentiate easily between 1 and 11.
Also this will make sure that even if the same version comes in end(say 1.9 in end) it will put it back in data1.
let newArr2 = ({ results }) =>
results.reduce((acc, item) => {
let key = "data" + /^(\d+)\.?.*/.exec(item.id)[1];
let found = acc.find(i => key in i);
found ? found[key].push(item) : acc.push({ [key]: [item] });
return acc;
}, []);

How to get the corresponding value from two objects

I have first data object which has a list of cafe, and second data object which has a list of cafe types.
I need find, get and display the corresponding type value from first data object and ID value from second data object.
For example: in list of cafe, I have Pinta with "type" : "3", it means that 3 is Bar from second object.
First object:
{
"list": {
"item": [
{
"ID": "31",
"name": "Staut",
"type": "1",
},
{
"ID": "34",
"name": "Pinta",
"type": "3",
}
]
}
}
And second object:
{
"list": {
"item": [
{
"ID": "1",
"name": "Restaurant",
},
{
"ID": "2",
"name": "Cafe",
},
{
"ID": "3",
"name": "Bar",
}
]
}
}
I can do it with Lodash. It is right, but I can't display it and it uses high memory.
getValues: function() {
_.forEach(CafeJSON.list.item, function(cafeValue) {
_.forEach(TypeJSON.list.item, function(typeValue){
if (cafeValue.type == typeValue.ID) {
console.log("Cafe name is: ", cafeValue.name, "and type is: ", typeValue.name)
}
})
})
}
Result:
I'd simplify the types object down to a object having key value pairs in the form of '3': 'Bar', then loop the items once, overriding the type property's value.
let list = {
"list": {
"item": [{
"ID": "31",
"name": "Staut",
"type": "1",
},
{
"ID": "34",
"name": "Pinta",
"type": "3",
}
]
}
}
let types = {
"list": {
"item": [{
"ID": "1",
"name": "Restaurant",
},
{
"ID": "2",
"name": "Cafe",
},
{
"ID": "3",
"name": "Bar",
}
]
}
}
let typesSimplified = types.list.item.reduce((a, b) => {
a[b.ID] = b.name;
return a;
}, {});
list.list.item.forEach(e => {
e.type = typesSimplified[e.type];
});
console.log(list);

Javascript create 2 arrays from object data

I have some data and I need a loop which creates 2 arrays...
So I first create the 2 arrays:
namelist = [];
countList = [];
{
"id": "622",
"name": "main",
"sub": {
"637": {
"id": "637",
"name": "name 1",
"stats": {
"count": 5
}
},
"638": {
"id": "638",
"name": "name 2",
"stats": {
"count": 10
}
}
}
}
The desired result for this example would be:
For namelist:
['name 1', 'name 2']
For countList:
[5, 10]
How can I do this?
var nameList = [];
var countList = [];
var myObj =
{
"id": "622",
"name": "main",
"sub": {
"637": {
"id": "637",
"name": "name 1",
"stats": {
"count": 5
}
},
"638": {
"id": "638",
"name": "name 2",
"stats": {
"count": 10
}
}
}
};
for(var key in myObj.sub){
nameList.push(myObj.sub[key].name);
countList.push(myObj.sub[key].stats.count);
}
console.log(nameList);
console.log(countList);
for(var key in obj.sub){
nameList.push(obj.sub[key].name);
countList.push(obj.sub[key].stats.count;
}
Object.keys may help you to walk through object properties. Example related to your object:
var namelist = [],
countList = [],
obj = {
"id": "622",
"name": "main",
"sub": {
"637": {
"id": "637",
"name": "name 1",
"stats": {
"count": 5
}
},
"638": {
"id": "638",
"name": "name 2",
"stats": {
"count": 10
}
}
}
};
Object.keys(obj.sub).forEach(function(item) {
namelist.push(obj.sub[item].name);
countList.push(obj.sub[item].stats.count);
});
console.log(namelist, countList);
Working example: https://jsfiddle.net/ry0zqweL/
Obviously, you can optimise it in many ways. It's just illustrating one of the many solutions.

How to Sort the JSON array in the controller of AngularJS?

Kindly help me in sorting the below JSON list in the controller and display in the view.
Actually orderBy filter sorting one level, But I need it sort even for childs recursively.
Input:
R2
-->S4
------>T5
------>T4
-->S3
R1
-->S2
------>T2
------>T1
-->S1
Output:
R1
-->S1
------>T1
------>T2
-->S2
R2
-->S3
------>T4
------>T5
-->S4
Please find the sample in Plunker.
http://plnkr.co/edit/JslHwJ1CBREKf6FgYHaZ?p=preview
var sortNames = function(arr){
arr = arr.sort(function(a,b){
return a.name > b.name;
})
for (var i = 0; i < arr.length; i++){
if (arr[i].childs){
sortNames(arr[i].childs)
}
}
return arr;
}
var names = [
{
"name": "Root1",
"Id": "2f3d17cb-d9e2-4e99-882d-546767f2765d",
"status": "",
"dispName": "",
"imageURL": "",
"childCount": "",
"childs": [
{
"name": "Sub1",
"Id": "ff8b3896-3b80-4e1b-be89-52a82ec9f98f",
"childs": [
{
"name": "Template1",
"Id": "ff8b3896-3b80-4e1b-be89-52a82ec9f981",
"status": "",
"dispName": "",
"imageURL": ""
},
{
"name": "Template2",
"Id": "ff8b3896-3b80-4e1b-be89-52a82ec9f982",
"status": "",
"dispName": "",
"imageURL": ""
}
]
},
{
"name": "Template3",
"Id": "ff8b3896-3b80-4e1b-be89-52a82ec9f981"
}
]
},
{
"name": "Root2",
"Id": "ea0586e7-02cf-4359-94ba-8d9623590dfe",
"childs": [
{
"name": "Sub2",
"Id": "6f1b3a60-d295-413e-92ef-1c713446e6c9",
"childs": [
{
"name": "Template4",
"Id": "6f1b3a60-d295-413e-92ef-1c713446e6c1"
},
{
"name": "Template5",
"Id": "6f1b3a60-d295-413e-92ef-1c713446e6c2"
}
]
}
]
}
];
sortNames(names);

Categories