Ordering JSON Objects using jQuery - javascript

I have the following JSON Object being loaded into my application and stored into a var called obj:
{
"items" : [
{
"name" : "item-1",
"group" : [
{
"groupName" : "name-1",
"groupPosition" : 2
},
{
"groupName" : "name-2",
"groupPosition" : 1
}]
},
{
"name" : "item-2",
"group" : [
{
"groupName" : "name-1",
"groupPosition" : 1
},
{
"groupName" : "name-2",
"groupPosition" : 2
}]
}]
}
I then do the following to go through it:
var groups = new Array();
var items = new Array();
$.each(obj.items, function(i,r){
var itemName = r.name;
$.each(r.group, function(index, record){
if ($.inArray(record.groupName) == -1) {
groups.push(record.groupName);
$('body').append('<div id="record.groupName"></div>');
}
$('#'+record.groupName).append('<div id="itemName">itemName</div>');
// At this point I'm stuck as the items get added in order of iteration,
// not according to their record.groupPosition value.
});
});
There will eventually be several hundred "items" each contained within an unset number of "groups".
The trouble I'm having is how to iterate through the JSON object using jQuery or good ol'JavaScript and display the items in the correct position within each group as the items and groups won't be listed inside the JSON object in sequential order.
Any help would be greatly appreciated!
Thank you.

Why not just give the group items the position index like this:
{
"items" : [
{
"name" : "item-1",
"group" : {
2:{
"groupName" : "name-1",
"groupPosition" : 2
},
1:{
"groupName" : "name-2",
"groupPosition" : 1
}}
},
{
"name" : "item-2",
"group" : {
1:{
"groupName" : "name-1",
"groupPosition" : 1
},
2:{
"groupName" : "name-2",
"groupPosition" : 2
}}
}]
}

Assuming you have a variable which is assigned to this:
var data = ...
you could use the $.each() method:
$.each(data.items, function(index, item) {
// here item.name will contain the name
// and if you wanted to fetch the groups you could loop through them as well:
$.each(item.group, function(i, group) {
// here you can use group.groupName and group.groupPosition
});
});
Arrays ([]) in javascript are 0 index based and preserve their order when you are iterating over them.

If I understood correctly your problem it is not about the sorting it self but how to link them to your dom nodes, solution: use classes with numbers.
For example:
$(".group"+items[1].group[0].grouposition").append(items[1].group[0].name);
// this will give append to the element with class="group1"
If you join this with having the html structure that is being generated to match the same names, then it won't be a problem and you don't have to sort them

Related

how to modify specific nested object in array in a document with mongodb? [duplicate]

My JSON currently looks like this:
{
"_id" : 393,
"item" : 34,
"comments" : [
{
"name" : "kevin",
"messages" : [
"item",
"item"
]
},
{
"name" : "ryan",
"messages" : [
"item",
"item"
]
}
]
}
How could I push new items onto the messages array for the first or second item in the comments array?
db.newcon.update({_id: 393}, { $push: { comments['kevin']: {messages: 39 } } })
Using $elemMatch and $ operator you can update your documents check below query :
db.collectionName.update({"_id":393,"comments":{"$elemMatch":{"name":"kevin"}}},
{"$push":{"comments.$.messages":39}})
Something like this will work:
var newMessage = '39';
comments.forEach(function(item) {
if (item.name === 'kevin') {
item.comments.push(newMessage);
}
});

Javascript, deep extend

So I have an object I'm trynig to deep extend into - right now the extend function works if the lowest level is just an array, So it looks like this :
function(base, next) {
var dataEntry = base.filter(function(it) {
return it.module === next.module;
})[0];
if (dataEntry) {
var diff = next.customUrl.filter(function(it) {
return dataEntry.customUrl.indexOf(it) === -1;
});
dataEntry.customUrl = dataEntry.customUrl.concat(diff).sort();
//_.extend(dataEntry, next);
} else {
base.push(next);
}
}
And this works if the object looks like :
[
{"name" : "one", "test" : ["1","2"]},
{"name" : "two", "test" : ["1","2"]}
]
However some things had to change and now the object looks like this :
[
{"name" : "one", "test" : [{"random1" : true},{"random2" : false}] },
{"name" : "two", "test" : [{"random3" : true},{"random4" : false}]}
]
Where the keys in the array is now an array of objects, and the objects keys are random. So If there was an object with the same key - replace the value (unless its the same, otherwise push a new object inside of there.
So for that object above I would pass this to merge into it for example:
{"name" : "one", "test" : [{"random2" : true}]}
So that would change the value of random2 to true, or something like this
{"name" : "one", "test" : [{"random18" : true}] }
where that would push in random 18 like so :
[
{"name" : "one", "test" : [{"random1" : true},{"random2" : false},{"random18" : true}] },
{"name" : "two", "test" : [{"random3" : true},{"random4" : false}]}
]
Unsure how to traverse deeper and merge. Thanks for reading!!
Edit : first stab at it -
function(base, next) {
var dataEntry = base.filter(function(it) {
return it.module === next.module;
})[0];
if (dataEntry) {
var allTags = [];
allTags.push.apply(allTags, dataEntry.customUrl);
allTags.push.apply(allTags, next.customUrl);
dataEntry.customUrl = allTags;
} else {
base.push(next);
}
}
Does not work because it does not cover over objects if they are the same, just pushes into array.
http://jsfiddle.net/p08ayvv8/
this fiddle shows you how jQuery can deal with (deep) extending objects.
See http://api.jquery.com/jquery.extend/ for a detailed explaination.
It is mentionable though that when preforming the second extension jQuery will prepend the old value of test to the array, thats why I added
o1.test = o1.test[0];

How to extract an array of fields from an array of JSON documents?

I have 2 mongodb collections, stu_creds and stu_profile. I first want to retrieve all the student records from stu_creds where stu_pref_contact is the email and then for those stu_ids I want to retrieve the complete profile from stu_profile. The problem is, the first query returns an array of JSON documents, with each document holding one field, the stu_id. Here is my query and the result:
db.stu_creds.find({"stu_pref_contact" : "email"}, {'_id' : 1})
Result:
[{ "_id" : ObjectId("51927cc93080baac04000001") },
{ "_id" : ObjectId("51927d7b3080baac04000002") },
{ "_id" : ObjectId("519bb011c5c5035b2a000002") },
{ "_id" : ObjectId("519ce3d09f047a192b000010") },
{ "_id" : ObjectId("519e6dc0f919cfdc66000003") },
{ "_id" : ObjectId("51b39be0c74f0e3d23000012") },
{ "_id" : ObjectId("51b39ca9c74f0e3d23000014") },
{ "_id" : ObjectId("51b39cb7c74f0e3d23000016") },
{ "_id" : ObjectId("51b39e87c74f0e3d23000018") },
{ "_id" : ObjectId("51b39f2fc74f0e3d2300001a") },
{ "_id" : ObjectId("51b39f47c74f0e3d2300001c") },
{ "_id" : ObjectId("518d454deb1e3a525e000009") },
{ "_id" : ObjectId("51bc8381dd10286e5b000002") },
{ "_id" : ObjectId("51bc83f7dd10286e5b000004") },
{ "_id" : ObjectId("51bc85cbdd10286e5b000006") },
{ "_id" : ObjectId("51bc8630dd10286e5b000008") },
{ "_id" : ObjectId("51bc8991dd10286e5b00000a") },
{ "_id" : ObjectId("51bc8a43dd10286e5b00000c") },
{ "_id" : ObjectId("51bc8a7ddd10286e5b00000e") },
{ "_id" : ObjectId("51bc8acadd10286e5b000010") }]
The thing is, I don't think I can use the above array as part of an $in clause for my second query to retrieve the student profiles. I have to walk through the array and and create a new array which is just an array of object ids rather than an array of JSON docs.
Is there an easier way to do this?
Use Array.map (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map). This allows you to perform a transform on each element of the array, returning you a new array of the transformed items.
var arrayOfIds = result.map(function(item){ return item._id; });
Array.map was introduced in ECMAScript 5. If you're using node.js, a modern browser, or an Array polyfill, it should be available to use.
Ummm, am I missing something or is all you want the following:
var results = [];
for(var i = 0; i < yourArray.length; i++) {
results.push(yourArray[i]._id);
}
You could use $or:
db.stu_profile.find({ $or : results }) // `results` is your list of ObjectId's
But it's considerably slower than $in, so I would suggest using one of the other answers ;)

How to get json object key name from collection and iterate

Below is my json structure. On success of collection.fetch() i'm looping through the structure.
Currently i use
this.collection.each(function(model) { .. }
How do i obtain key name like plants, animals and instead loop using the names.
JSON
var jsonObj = { // 0 - recommended , 1 - New
"plants" : [
{
"title" : "title1",
"desc": "description.."
},
{
"title" : "titl2",
"desc": "description."
}
],
"animals" : [
{
"title" : "title1",
"desc": "description.."
},
{
"title" : "titl2",
"desc": "description."
}
]
};
Snapshot of collection
This would work, but you'd use a normal for loop, not "each":
for(i in jsonObj){
alert(i);
}
here is a fjsfiddle: http://jsfiddle.net/r5nwP/
Is that what you're after?
You can use the underscore keys to get a list of names:
var thenames =_.keys(yourobject);
In this case thenames will contain a list of the keys you are looking for. Here is the documentation for it:
http://underscorejs.org/#keys
keys_.keys(object)
Retrieve all the names of the object's properties.
_.keys({one : 1, two : 2, three : 3});
=> ["one", "two", "three"]

Is this a javascript array with objects in it?

Square brackets is an array, and curly brackets are objects correct?
What exactly is this data structure:
Some.thing = [ {
"swatch_src" : "/images/91388044000.jpg",
"color" : "black multi",
"inventory" : {
"F" : [ 797113, 797114 ],
"X" : [ 797111, 797112 ]
},
"images" : [ {
"postfix" : "jpg?53_1291146215000",
"prefix" : "/images/share/uploads/0000/0000/5244/52445892"
}, {
"postfix" : "jpg?53_1291146217000",
"prefix" : "/images/share/uploads/0000/0000/5244/52445904"
}, {
"postfix" : "jpg?53_1291146218000",
"prefix" : "/images/share/uploads/0000/0000/5244/52445909"
} ],
"skus" : [ {
"sale_price" : 199,
"sku_id" : 797111,
"msrp_price" : 428,
"size" : "s"
}, {
"sale_price" : 199,
"sku_id" : 797112,
"msrp_price" : 428,
"size" : "m"
}, {
"sale_price" : 199,
"sku_id" : 797113,
"msrp_price" : 428,
"size" : "l"
}, {
"sale_price" : 199,
"sku_id" : 797114,
"msrp_price" : 428,
"size" : "xl"
} ],
"look_id" : 37731360
} ];;
Some.thing is an array [] containing a single object {}. Some of the properties of this object are strings while others are arrays.
The single object appears to be describing a product.
Yes, an array of objects with nested arrays within. (or in this case one single element contained within an array.)
Some.thing[0] refers to everything you have listed. From there, you have an object containing:
var obj = Some.thing[0];
obj.swatch_src // contains "/images/91388044000.jpg"
obj.color // contains "black multi"
...
obj.inventory // (another object
obj.inventory.F // array of [797113, 797114]
...
obj.images // array of objects
obj.images[0].postfix // contains "jpg?53_1291146215000"
obj.images[0].prefix // contains "/images/share/uploads/0000/0000/5244/52445892"
...
This is captured from Chrome Console. You can try it yourself :)
Yes, this is called JSON: JavaScript Object Notation.

Categories