Related
I have an object that looks like the following {key: id numbers}
var obj = {
"c4ecb": {id: [3]},
"a4269": {id: [34,36]},
"d76fa": {id: [54,55,60,61]},
"58cb5": {id: [67]}
}
How do I loop each above id in the following array, and return the label?
var response =
{
"success": true,
"data": [
{
"key": "c4ecb",
"name": "fruits",
"options": [
{
"label": "strawberry",
"id": 3
},
{
"label": "apple",
"id": 4
},
{
"label": "pineapple",
"id": 5
},
{
"label": "Other",
"id": 31
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "a4269",
"name": "vegetables",
"options": [
{
"label": "lettuce",
"id": 34
},
{
"label": "cucumber",
"id": 35
},
{
"label": "radish",
"id": 36
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "d76fa",
"name": "pasta",
"options": [
{
"label": "spaghetti",
"id": 54
},
{
"label": "rigatoni",
"id": 55
},
{
"label": "linguine",
"id": 56
},
{
"label": "lasagna",
"id": 60
},
{
"label": "fettuccine",
"id": 61
}
],
}
]
}
Finally, what I want to do is look up the key and return a string of id values.
For example, input c4ecb and output strawberry. Input a4269 and output lettuce, radish. Input d76fa and output "spaghetti, rigatoni, lasagna, fettuccine"
I think to join the multiple labels output into one string I could use something like
array.data.vegetables.map(vegetables => vegetables.value).join(', ')].toString();
So in the end I want to have something like
var fruits = [some code that outputs "strawberry"];
var vegetables = [some code that outputs "lettuce, radish"];
var pasta = [some code that outputs "spaghetti, rigatoni, lasagna, fettuccine"];
What I've tried so far:
The following loop will return the id only if there is one id to be called for: e.g. only in case one where {id: 3} but returns null in cases like {id: 34,36} (because it's looking for '34,36' in id, which doesn't exist - I need to look for each one individually.
response.data.forEach(({key, options}) => {
if (obj[key]) {
options.forEach(({id, label}) => {
if (id == obj[key].id) obj[key].label = label;
});
}
});
console.log(obj)
Filter the response object to focus on the category that matches the id.
Map over the options array and select the items which appear in obj[id].
Finally convert the filtered results to a string.
See filteredLabelsAsString() function below for implementation.
var obj = {
"c4ecb": {"id": [3]},
"a4269": {"id": [34,36]},
"d76fa": {"id": [54,55,60,61]},
"58cb5": {"id": [67]}
}
var response =
[{
"success": true,
"data": [
{
"key": "c4ecb",
"name": "fruits",
"options": [
{
"label": "strawberry",
"id": 3
},
{
"label": "apple",
"id": 4
},
{
"label": "pineapple",
"id": 5
},
{
"label": "Other",
"id": 31
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "a4269",
"name": "vegetables",
"options": [
{
"label": "lettuce",
"id": 34
},
{
"label": "cucumber",
"id": 35
},
{
"label": "radish",
"id": 36
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "d76fa",
"name": "pasta",
"options": [
{
"label": "spaghetti",
"id": 54
},
{
"label": "rigatoni",
"id": 55
},
{
"label": "linguine",
"id": 56
},
{
"label": "lasagna",
"id": 60
},
{
"label": "fettuccine",
"id": 61
}
],
}
]
}];
function filteredLabelsAsString(obj_key, obj, content=response) {
// sanity check: obj must contain obj_key
if (Object.keys(obj).includes(obj_key)) {
return content.filter((item) => {
// filter content using value of obj_key
return item.data[0].key == obj_key;
}).map((item) => {
// item : { success: true, data: [] }
// map over options array
return item.data[0].options.map((opt) => {
// option : {id, label}
// return the label if the id is in the obj object's list
if (obj[item.data[0].key].id.includes(opt.id))
return opt.label;
}).filter((label) => {
// filter out empty items
return label !== undefined;
});
}).join(",");
}
// if obj does not contain obj_key return empty string
return "";
}
console.log("fruits: " + filteredLabelsAsString("c4ecb", obj));
console.log("vegetables: " + filteredLabelsAsString("a4269", obj));
console.log("pasta: " + filteredLabelsAsString("d76fa", obj));
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;
}, []);
I'm querying data, where the structure is something like this.
I have two models, FoodDrinks and Cuisines. They have many to many relation.
Now on the following query
{
"filter": {
"include": "cuisines"
}
}
I am getting the following results.
[
{
"id": 1,
"name": "Biryani",
"cuisines": [
{
"id": 1,
"name": "Mughlai"
},
{
"id": 2,
"name": "North Indian"
},
{
"id": 3,
"name": "Afghani"
}
]
},
{
"id": 2,
"name": "Chhole Bhature",
"cuisines": [
{
"id": 2,
"name": "North Indian"
}
]
},
{
"id": 3,
"name": "Amritsari Naan",
"cuisines": [
{
"id": 2,
"name": "North Indian"
},
{
"id": 6,
"name": "Punjabi"
},
]
}
]
Now I want only those food drinks which have cuisines from the following array.
let cuisinesIDs = ["1", "2"]
What will the following query for that?
I guess something like the below should work:
{
"filter": {
"include": "cuisines"
},
"where": {
"cuisines.id": {
"inq": cuisinesIDs
}
}
}
It might be the same answer as #Behrooz, but I would try:
{
"filter": {
"include": {
relation: 'cuisines',
scope: {
where: {
id: {inq: cuisinesIDs}
}
}
}
}
}
I have been reading some posts which are related to my question, whereas I have not been able to find a proper solution for what I'm trying to do hear.
I have this JSON file that I am obtaining directly from my database via a sql query:
[
{
"scenario": "scenario-483d742c-4492-4a4f-95fa-7ccceac8bb18",
"data": [
{
"date": "2018-05-21",
"price": 14.173041264216105
}
]
},
{
"scenario": "scenario-483d742c-4492-4a4f-95fa-7ccceac8bb18",
"data": [
{
"date": "2018-05-22",
"price": 42.94691197077433
}
]
},
{
"scenario": "scenario-c705069f-fa53-4ff3-9f07-3fcbf9dc8d15",
"data": [
{
"date": "2018-05-22",
"price": 42.94691197077433
}
]
},
{
"scenario": "scenario-c705069f-fa53-4ff3-9f07-3fcbf9dc8d15",
"data": [
{
"date": "2018-05-22",
"price": 42.94691197077433
}
]
},
{
"scenario": "scenario-d58bb001-d7ed-4744-8f6c-8377519c7a99",
"data": [
{
"date": "2018-05-22",
"price": 42.94691197077433
}
]
},
{
"scenario": "scenario-d58bb001-d7ed-4744-8f6c-8377519c7a99",
"data": [
{
"date": "2018-05-22",
"price": 42.94691197077433
}
]
}
]
My objectif is to be able to sort/transform this json object to a new json object which is classified by the scenario, so, something that looks like:
[
{
"scenario": "scenario-483d742c-4492-4a4f-95fa-7ccceac8bb18",
"data": [
{
"date": "2018-05-21",
"price": 14.173041264216105
},
{
"date": "2018-05-22",
"price": 42.94691197077433
}
]
},
{
"scenario": "scenario-c705069f-fa53-4ff3-9f07-3fcbf9dc8d15",
"data": [
{
"date": "2018-05-22",
"price": 42.94691197077433
},
{
"date": "2018-05-22",
"price": 42.94691197077433
}
]
},
{
"scenario": "scenario-d58bb001-d7ed-4744-8f6c-8377519c7a99",
"data": [
{
"date": "2018-05-22",
"price": 42.94691197077433
},
{
"date": "2018-05-22",
"price": 42.94691197077433
}
]
I have been trying some javascript selfmade functions but I have not obtainend the desired result.
This is the last thing I've tried:
let estructura = [];
for (var j =0; j<obj.length; j++){
for (var i=0; i<estructura.length; i++){
if(obj[j]['scenario'] == estructura[i]['scenario']){
estructura[i]['data'].push(obj[j]['data'])
} else {
console.log("no match, we add the scenario to estructura")
estructura.push(
{
scenario:obj[j]['scenario'],
data: []
})
}
}
}
Thank you
You can achieve this easily with built-in functions like reduce. Iterate over the input, grouping into an object indexed by scenario, creating a object with a data array if the scenario doesn't exist yet, and push to that array:
const input=[{"scenario":"scenario-483d742c-4492-4a4f-95fa-7ccceac8bb18","data":[{"date":"2018-05-21","price":14.173041264216105}]},{"scenario":"scenario-483d742c-4492-4a4f-95fa-7ccceac8bb18","data":[{"date":"2018-05-22","price":42.94691197077433}]},{"scenario":"scenario-c705069f-fa53-4ff3-9f07-3fcbf9dc8d15","data":[{"date":"2018-05-22","price":42.94691197077433}]},{"scenario":"scenario-c705069f-fa53-4ff3-9f07-3fcbf9dc8d15","data":[{"date":"2018-05-22","price":42.94691197077433}]},{"scenario":"scenario-d58bb001-d7ed-4744-8f6c-8377519c7a99","data":[{"date":"2018-05-22","price":42.94691197077433}]},{"scenario":"scenario-d58bb001-d7ed-4744-8f6c-8377519c7a99","data":[{"date":"2018-05-22","price":42.94691197077433}]}]
console.log(
Object.values(input.reduce((a, { scenario, data }) => {
if (!a[scenario]) a[scenario] = { scenario, data: [] };
a[scenario].data.push(data[0]);
return a;
}, {}))
);
"items": {
"hotdrinks": [
{
"id": "9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price": 20,
"name": "Tea",
"img": "../assets/img/HotDrinks/1_udupibhavan.jpg"
},
{
"id": "9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price": 25,
"name": "Coffee",
"img": "../assets/img/Hot Drinks/2_udupibhavan.jpg"
},
{
"id": "9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price": 50,
"name": "Hot Milk",
"img": "../assets/img/Hot Drinks/3_udupibhavan.jpg"
},
{
"id": "9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price": 70,
"name": "Horlicks",
"img": "../assets/img/Hot Drinks/4_udupibhavan.jpg"
},
{
"id": "9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price": 80,
"name": "Badam Milk",
"img": "../assets/img/Hot Drinks/5_udupibhavan.jpg"
}
],
}
json i want to achieve using javascript. im just new to handling arrays and objects. thanksfound the answer given by Jeeva which works perfectly
future answers are welcome since we can know diffferent methods to achieve the same json object
dataArray = [
{title:"Hotdrinks",
content: [{
"id": "9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price": 20,
"name": "Tea",
"img": "../assets/img/HotDrinks/1_udupibhavan.jpg"
},
{
"id": "9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price": 80,
"name": "Badam Milk",
"img": "../assets/img/Hot Drinks/5_udupibhavan.jpg"
}
]}
You can use like this. This can be achieved by iterating the object.
const data = {
"items":{
"hotdrinks":[
{
"id":"9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price":20,
"name":"Tea",
"img":"../assets/img/HotDrinks/1_udupibhavan.jpg"
},
{
"id":"9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price":25,
"name":"Coffee",
"img":"../assets/img/Hot Drinks/2_udupibhavan.jpg"
},
{
"id":"9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price":50,
"name":"Hot Milk",
"img":"../assets/img/Hot Drinks/3_udupibhavan.jpg"
},
{
"id":"9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price":70,
"name":"Horlicks",
"img":"../assets/img/Hot Drinks/4_udupibhavan.jpg"
},
{
"id":"9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price":80,
"name":"Badam Milk",
"img":"../assets/img/Hot Drinks/5_udupibhavan.jpg"
}
]
}
}
var dataArray = []
for(k in data.items){
var dataObj = {}
dataObj.title = k
dataObj.content = data.items[k] //You can also access the object values by using bracket ([]) notation
dataArray.push(dataObj)
}
console.log(JSON.stringify(dataArray))
The above expected output json is not valid. We can achieve the following.
[{"title":"Hotdrinks"}, {"content": [
{
"id":"9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price":20,
"name":"Tea",
"img":"../assets/img/HotDrinks/1_udupibhavan.jpg"
},
{
"id":"9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price":25,
"name":"Coffee",
"img":"../assets/img/Hot Drinks/2_udupibhavan.jpg"
},
{
"id":"9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price":50,
"name":"Hot Milk",
"img":"../assets/img/Hot Drinks/3_udupibhavan.jpg"
},
{
"id":"9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price":70,
"name":"Horlicks",
"img":"../assets/img/Hot Drinks/4_udupibhavan.jpg"
},
{
"id":"9aa113b4-1e4e-4cde-bf9d-8358fc78ea4f",
"price":80,
"name":"Badam Milk",
"img":"../assets/img/Hot Drinks/5_udupibhavan.jpg"
}
]}]
If you are okay with this then i'll give you the sample code for the same.