I have a following data structure, array of dictionaries
[
{
"id": 1,
"name": "Some Name 1",
"topics": [
{
"id": 3,
"name": "Topic Name",
"topics": [],
},
{
"id": 3,
"name": "Topic Name",
"topics": [],
}
]
},
{
"id": 2,
"name": "Some Name 2",
"topics": [
{
"id": 3,
"name": "Topic Name",
"topics": [],
},
{
"id": 3,
"name": "Topic Name",
"topics": [],
}
]
},
[
{
"id": 1,
"name": "Some Name 2",
"topics": [
{
"id": 1,
"name": "Topic Name 1",
"topics": [],
},
{
"id": 2,
"name": "Topic Name 2",
"topics": [],
}
]
},
{
"id": 2,
"name": "Some Name 1",
"topics": [
{
"id": 3,
"name": "Topic Name",
"topics": [],
},
{
"id": 3,
"name": "Topic Name",
"topics": [],
}
]
},
I want to essentially be able to combine the arrays within each dictionary if I have the same id, so for each dictionary i will have higher level dictionary items being the same and essentially combine those together to avoid duplication. Preferably i would like it to be recursively being that in case the topics within topics are also duplicate (you can assume the order is always respected).
I would appreciate if you could share a solution to this
This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 2 years ago.
I have the following object:
var myObj={
"name": "Chatik",
"type": "public_supergroup",
"id": 9947542893,
"messages": [
{
"id": 1,
"type": "service",
"date": "2019-11-11T21:45:33",
"actor": "Chatik",
"actor_id": 9947542893,
"action": "migrate_from_group",
"title": "Chatik",
"text": ""
},
{
"id": 2,
"type": "message",
"date": "2019-11-11T21:51:22",
"from": "Korney Chukovsky",
"from_id": 4528246494,
"text": "Чому никто не вкатывается?"
},
{
"id": 3,
"type": "message",
"date": "2019-11-11T21:55:13",
"from": "Korney Chukovsky",
"from_id": 4528246494,
"text": "Бля, я даже в своей собственной конфе один."
},
{
"id": 7,
"type": "message",
"date": "2019-11-11T22:05:48",
"from": "Андрей",
"from_id": 4855779304,
"text": "ты откуда?"
}
]};
How do I create a script that would output all "text properties from each "elements" within the curly braces but only if the "from_id" property matches a certain value?
For example if my "from id" value is 4528246494, then "text" value should be outputted to the console, then proceed to check the next "element", if the value is not 4528246494, then skip, etc.
You just have to access message and grab the second element as normal property accessing
var myObj = {
"name": "Chatik",
"type": "public_supergroup",
"id": 9947542893,
"messages": [{
"id": 1,
"type": "service",
"date": "2019-11-11T21:45:33",
"actor": "Chatik",
"actor_id": 9947542893,
"action": "migrate_from_group",
"title": "Chatik",
"text": ""
},
{
"id": 2,
"type": "message",
"date": "2019-11-11T21:51:22",
"from": "Korney Chukovsky",
"from_id": 4528246494,
"text": "Чому никто не вкатывается?"
},
{
"id": 3,
"type": "message",
"date": "2019-11-11T21:55:13",
"from": "Korney Chukovsky",
"from_id": 4528246494,
"text": "Бля, я даже в своей собственной конфе один."
}
]
};
console.log(myObj.messages[1].text)
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I've a JSON response as below.I'm using nested JSON data from my GeoRegionCountries APIController & custom class TreeView is used to format the data as per the required nested structure of plugin I'm using. I am using a combo multi select Treeview using this jquery plugin Multi-Select Drop Down Tree Plugin you can see it by this link jquery plugin Multi-Select Drop Down Tree Plugin
[
{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [
{
"Id": 7,
"Title": "Northwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1,
"Subs": []
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1,
"Subs": []
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1,
"Subs": []
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null,
"Subs": []
},
{
"Id": 3,
"Title": "France",
"ParentId": null,
"Subs": []
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null,
"Subs": []
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null,
"Subs": []
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null,
"Subs": []
}
]
I want to remove all "Subs" with empty array.
[
{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [
{
"Id": 7,
"Title": "Northwest",
"ParentId": 1
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null
},
{
"Id": 3,
"Title": "France",
"ParentId": null
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null
}
]
What is the best way to deep clean this? I tried different solutions in Stackopverflow but all i got is Object object in place of empty Subs - which i don't want.
[
{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [
{
"Id": 7,
"Title": "Northwest",
"ParentId": 1,
Object object
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1,
Object object
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1,
Object object
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1,
Object object
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1,
Object object
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null,
Object object
},
{
"Id": 3,
"Title": "France",
"ParentId": null,
Object object
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null,
Object object
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null,
Object object
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null,
Object object
}
]
which is not i want
You can use _.transform() to recursively check for a specific key (Subs), and remove it if it's value is empty:
const { transform, isObject, isEmpty } = _;
const removeEmpty = (obj, key) =>
transform(obj, (r, v, k) => {
if(k === key && isEmpty(v)) return;
r[k] = isObject(v) ? removeEmpty(v, key) : v;
});
const tree = [{"Id":1,"Title":"United States","ParentId":null,"Subs":[{"Id":7,"Title":"Northwest","ParentId":1,"Subs":[]},{"Id":8,"Title":"Northeast","ParentId":1,"Subs":[]},{"Id":9,"Title":"Central","ParentId":1,"Subs":[]},{"Id":10,"Title":"Southwest","ParentId":1,"Subs":[]},{"Id":18,"Title":"Southeast","ParentId":1,"Subs":[]}]},{"Id":2,"Title":"Canada","ParentId":null,"Subs":[]},{"Id":3,"Title":"France","ParentId":null,"Subs":[]},{"Id":4,"Title":"Germany","ParentId":null,"Subs":[]},{"Id":5,"Title":"Australia","ParentId":null,"Subs":[]},{"Id":6,"Title":"United Kingdom","ParentId":null,"Subs":[]}]
const result = removeEmpty(tree, 'Subs');
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
The correct answer would be this:
let array = [
{
'Id': 1,
'Title': 'United States',
'ParentId': null,
'Subs': [
{
'Id': 7,
'Title': 'Northwest',
'ParentId': 1,
'Subs': []
},
{
'Id': 8,
'Title': 'Northeast',
'ParentId': 1,
'Subs': []
},
{
'Id': 9,
'Title': 'Central',
'ParentId': 1,
'Subs': []
},
{
'Id': 10,
'Title': 'Southwest',
'ParentId': 1,
'Subs': []
},
{
'Id': 18,
'Title': 'Southeast',
'ParentId': 1,
'Subs': []
}
]
},
{
'Id': 2,
'Title': 'Canada',
'ParentId': null,
'Subs': []
},
{
'Id': 3,
'Title': 'France',
'ParentId': null,
'Subs': []
},
{
'Id': 4,
'Title': 'Germany',
'ParentId': null,
'Subs': []
},
{
'Id': 5,
'Title': 'Australia',
'ParentId': null,
'Subs': []
},
{
'Id': 6,
'Title': 'United Kingdom',
'ParentId': null,
'Subs': []
}
]
let newArray = array.map(item=> {
if (item.Subs.length===0){
delete item.Subs
return item
}
item.Subs = item.Subs.map(item=>{
if (item.Subs.length===0){
delete item.Subs
return item
}
})
return item
}
)
console.log(newArray)
let data = [
{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [
{
"Id": 7,
"Title": "Northwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1,
"Subs": []
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1,
"Subs": []
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1,
"Subs": []
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null,
"Subs": []
},
{
"Id": 3,
"Title": "France",
"ParentId": null,
"Subs": []
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null,
"Subs": []
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null,
"Subs": []
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null,
"Subs": []
}
];
data = data.map(row=>{
if (!row.Subs.length) {
let {Subs,...r} = row;
return r;
} return row
})
console.log(data);
write two functions and pass the function that iterates through your array to a map function on data as shown below
function formatData(val) {
if (val.Subs.length > 0) val.Subs.map(a => a.Subs.length > 0 ? formatData(a.Subs) : deleteSubs(a));
else deleteSubs(val);
return val;
}
function deleteSubs(val) {
delete val.Subs;
}
var data = [{
"Id": 1,
"Title": "United States",
"ParentId": null,
"Subs": [{
"Id": 7,
"Title": "Northwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 8,
"Title": "Northeast",
"ParentId": 1,
"Subs": []
},
{
"Id": 9,
"Title": "Central",
"ParentId": 1,
"Subs": []
},
{
"Id": 10,
"Title": "Southwest",
"ParentId": 1,
"Subs": []
},
{
"Id": 18,
"Title": "Southeast",
"ParentId": 1,
"Subs": []
}
]
},
{
"Id": 2,
"Title": "Canada",
"ParentId": null,
"Subs": []
},
{
"Id": 3,
"Title": "France",
"ParentId": null,
"Subs": []
},
{
"Id": 4,
"Title": "Germany",
"ParentId": null,
"Subs": []
},
{
"Id": 5,
"Title": "Australia",
"ParentId": null,
"Subs": []
},
{
"Id": 6,
"Title": "United Kingdom",
"ParentId": null,
"Subs": []
}
]
console.log(data.map(formatData))
I am relatively new to Knockout.js and have a question regarding the creating of the view model.
What I am currently doing is:
viewModel = {
Menu: ko.observableArray(ko.utils.parseJson(data)),
editMenu: function (menu) {
ko.applyBindings(menu, document.getElementById("MenuCategories"));
$("#MenuCategories").bPopup();
}
There is more than one function, but trying to keep it short.
What I want to do is use the mapping plugin because my json data that I am using contains arrays of objects with each object containing an array and each object in that array also contains an array. What the JSON looks like:
[
{
"Id": 1,
"Name": "Test 5",
"Description": "Testing menu",
"BeveragesMenu": false,
"Active": true,
"Categories": [
{
"Id": 1,
"Name": "Test 1",
"Active": true,
"MenuItems": [
{
"Id": 1,
"Name": "Food",
"Description": "2 Eggs and Bread",
"Price": 50,
"DateBased": false,
"PriceOnRequest": false,
"DateFrom": null,
"DateTo": null,
"Active": true
}
]
},
{
"Id": 2,
"Name": "Test 2",
"Active": true,
"MenuItems": [
]
},
{
"Id": 1004,
"Name": "test",
"Active": true,
"MenuItems": [
]
},
{
"Id": 1005,
"Name": "Test 4",
"Active": true,
"MenuItems": [
]
}
]
},
{
"Id": 92,
"Name": "Test 4",
"Description": "",
"BeveragesMenu": false,
"Active": false,
"Categories": [
{
"Id": 1006,
"Name": "Test 1",
"Active": true,
"MenuItems": [
{
"Name": "Test",
"Description": "",
"Price": "",
"DateBased": false,
"PriceOnRequest": false
}
]
}
]
},
{
"Id": 93,
"Name": "Test 6",
"Description": "",
"BeveragesMenu": false,
"Active": false,
"Categories": [
]
},
{
"Id": 94,
"Name": "Test 9",
"Description": "",
"BeveragesMenu": false,
"Active": false,
"Categories": [
]
},
{
"Id": 95,
"Name": "Test 20]",
"Description": "",
"BeveragesMenu": false,
"Active": false,
"Categories": [
{
"Id": 4,
"Name": "Test 6666",
"Active": true,
"MenuItems": [
]
}
]
},
{
"Id": 96,
"Name": "Test 444",
"Description": "",
"BeveragesMenu": false,
"Active": false,
"Categories": [
{
"Id": 3,
"Name": "Test 555",
"Active": true,
"MenuItems": [
]
},
{
"Id": 5,
"Name": "Test 6666",
"Active": true,
"MenuItems": [
]
},
{
"Id": 1003,
"Name": "test 777",
"Active": true,
"MenuItems": [
]
}
]
}
]
Sorry for the long JSON code paste.
So now I am running into problems when updating certain parts of the objects within arrays withing objects etc.
So I taught that the mapping plugin might solve my problem as it creates all arrays as observable and I am assuming that is my problem.
So I tried:
viewModel = {
Menu: ko.mapping.fromJSON(ko.utils.parseJson(data)),
//Menu: ko.observableArray(ko.utils.parseJson(data)),
editMenu: function (menu) {
ko.applyBindings(menu, document.getElementById("MenuCategories"));
$("#MenuCategories").bPopup();
},
But then none of my binding are working and I can't seem to find the cause, any advice or tips on this matter would be appreciated.
Here is a Fiddle of all the things I have tried. http://jsfiddle.net/armandvdwalt/pjJc2/3/
Thanks
Try this fiddle, I switched the order of the resources. You were referencing the mapping plugin before knockout which was generating a script error about not recognizing "ko." Also, you don't need to use ko.utils.parseJson when using fromJSON, as fromJSON expects JSON as an argument.
I have the following json output from a webservice:
[
{
"subCategories": [
{
"subCategories": [],
"menuItems": [],
"id": 2,
"title": "First Course",
"type": "Menu Section",
"categoryID": 9,
"isActive": true,
"orderIndex": 7
}, {
"subCategories": [],
"menuItems": [
{
"id": 0,
"price": 30,
"title": "Meat",
"ingredients": "Bread, Pate, Cilantro, Turkey.",
"cookingTimeInMinutes": 6,
"isActive": true,
"picture": "",
"categoryID": 3,
"orderIndex": 2
}],
"id": 3,
"title": "Banh Mi",
"type": "Food Item",
"categoryID": 9,
"isActive": true,
"orderIndex": 1
}],
"menuItems": [
{
"id": 1,
"price": 1,
"title": "Soup",
"ingredients": "Water, Good Stuffs, Noodles.",
"cookingTimeInMinutes": 10,
"isActive": true,
"picture": "",
"categoryID": 9,
"orderIndex": 4
}, {
"id": 3,
"price": 12,
"title": "Egg Sandwich",
"ingredients": "Egg, Sandwich",
"cookingTimeInMinutes": 6,
"isActive": true,
"picture": "",
"categoryID": 9,
"orderIndex": 3
}],
"id": 9,
"title": "Lunch",
"type": "Menu Section",
"categoryID": null,
"isActive": true,
"orderIndex": 0
}, {
"subCategories": [],
"menuItems": [],
"id": 7,
"title": "Snack",
"type": "Menu Section",
"categoryID": null,
"isActive": true,
"orderIndex": 8
}, {
"subCategories": [],
"menuItems": [],
"id": 6,
"title": "First Course",
"type": "Menu Section",
"categoryID": null,
"isActive": true,
"orderIndex": 5
}, {
"subCategories": [],
"menuItems": [
{
"id": 2,
"price": 3,
"title": "Salad",
"ingredients": "Veggies",
"cookingTimeInMinutes": 5,
"isActive": true,
"picture": "",
"categoryID": null,
"orderIndex": 9
}],
"id": -1,
"title": "Other",
"type": "Menu Section",
"categoryID": null,
"isActive": true,
"orderIndex": 1000
}]
And I have the following javascript snippet that is supposed to iterate over mentioned json and turn it into divs:
<script type="text/javascript">
/* wait until the document has finished loading before loading
* the rest of the content
*/
$(document).ready(function(){
function divifyCategory(containerID, gingerWebCategory){
$('#' + containerID).append(
$('<div class="category" id="' + gingerWebCategory.id + '">' + gingerWebCategory.title + '</div>')
);
for(menuItem in gingerWebCategory.menuItems){
$('.category#' + gingerWebCategory.id).append(
$('<div class="menuItem" id="' + menuItem.id + '">' + menuItem.title + '</div>')
);
}
}
// load menu from web service
$.get('http://localhost:50730/GingerWeb.asmx/getMenu', function(data){
var data = eval(data);
for(var i=0; i<data.length; i++){
divifyCategory(data[i]);
}
});
});
</script>
Any idea on why I get this error message in Chrome:
Uncaught Error: Syntax error, unrecognized expression: #[object
Object]
?
Your json object is an array of objects. When you pass data[i], you are passing the first element in the array, an object, and treating it like a string (containerID). You need to get the ID from the object you're passing.
I suppose datais json string mentioned at the very beginning of the post. data is an array of objects. So there
for(var i=0; i<data.length; i++){
divifyCategory(data[i]);
}
object has been passed to function divifyCategory which expects string as the first parameter. And that parameter is used like string there
$('#' + containerID)
in the runtime you get $('#[object Object]'). It is unxpected situation.
I hope it helps.