I have two object JSON which having hierachical structure. I need to compare each object inside rowset in JSON. And where ever the value not gettng equal
then i have to addd one flag on corresponding object.
Please hava a look at my JSONs and give solution for that. If not angular atleast i have to achieve in Javascript.
Thanks in advance...
JSON1
{"entityinfo":{"entity":"Customer29Jan16","tenantid":"292FEC76-5F1C-486F-85A5-09D88096F098","timestamp":"2015-12-15T10:16:06.322Z"},"collections":{"Customer29Jan16":{"rowset":[{"CuId":"123","Name":"Ranjini","Quantity":"60","Rate":"60","Amount":"3600"}],"meta":{"parentreference":"***","pkname":"***","fkname":"***"},"rowfilter":[]},"Customer29Jan16Obj":{"rowset":[{"CuObjId":"456","FullAddress":"Electronic City","ObjAddr":"Bangalore","ObjName":"Testing"}],"meta":{"parentreference":"***","pkname":"***","fkname":"***"},"rowfilter":[]}}}
JSON2
{"entityinfo":{"entity":"Customer29Jan16","tenantid":"292FEC76-5F1C-486F-85A5-09D88096F098","timestamp":"2015-12-15T10:16:06.322Z"},"collections":{"Customer29Jan16":{"rowset":[{"CuId":"123","Name":"Vijay","Quantity":"60","Rate":"60","Amount":"3600"}],"meta":{"parentreference":"***","pkname":"***","fkname":"***"},"rowfilter":[]},"Customer29Jan16Obj":{"rowset":[{"CuObjId":"456","FullAddress":"SilkBoard","ObjAddr":"Bangalore","ObjName":"Testing"}],"meta":{"parentreference":"***","pkname":"***","fkname":"***"},"rowfilter":[]}}}
Use angular.equals(o1,o2) . It does deep comparison and does not depend on the order of the keys
angular.equals(JSON1, JSON2); // return boolean (true or false) based on the comparison
refer : Angularjs Docs
I've made an starting example for you to build on. You can play with it here.
JavaScript
var json1 = {"entityinfo":{"entity":"Customer29Jan16","tenantid":"292FEC76-5F1C-486F-85A5-09D88096F098","timestamp":"2015-12-15T10:16:06.322Z"},"collections":{"Customer29Jan16":{"rowset":[{"CuId":"123","Name":"Ranjini","Quantity":"60","Rate":"60","Amount":"3600"}],"meta":{"parentreference":"***","pkname":"***","fkname":"***"},"rowfilter":[]},"Customer29Jan16Obj":{"rowset":[{"CuObjId":"456","FullAddress":"Electronic City","ObjAddr":"Bangalore","ObjName":"Testing"}],"meta":{"parentreference":"***","pkname":"***","fkname":"***"},"rowfilter":[]}}};
var json2 = {"entityinfo":{"entity":"Customer29Jan16","tenantid":"292FEC76-5F1C-486F-85A5-09D88096F098","timestamp":"2015-12-15T10:16:06.322Z"},"collections":{"Customer29Jan16":{"rowset":[{"CuId":"123","Name":"Vijay","Quantity":"60","Rate":"60","Amount":"3600"}],"meta":{"parentreference":"***","pkname":"***","fkname":"***"},"rowfilter":[]},"Customer29Jan16Obj":{"rowset":[{"CuObjId":"456","FullAddress":"SilkBoard","ObjAddr":"Bangalore","ObjName":"Testing"}],"meta":{"parentreference":"***","pkname":"***","fkname":"***"},"rowfilter":[]}}};
function compareJSON(json1, json2) {
var objectsDiffering = [];
compareJSONRecursive(json1, json2, objectsDiffering);
return objectsDiffering;
}
function compareJSONRecursive(json1, json2, objectsDiffering) {
for(prop in json1) {
if(json2.hasOwnProperty(prop)) {
switch(typeof(json1[prop])) {
case "object":
compareJSONRecursive(json1[prop], json2[prop], objectsDiffering);
break;
default:
if(json1[prop] !== json2[prop]) {
objectsDiffering.push(json1);
}
break;
}
}
else {
objectsDiffering.push(json1);
break;
}
}
}
var differing = compareJSON(json1, json2);
console.log(JSON.stringify(differing));
//Logs: [{"CuId":"123","Name":"Ranjini","Quantity":"60","Rate":"60","Amount":"3600"},{"CuObjId":"456","FullAddress":"Electronic City","ObjAddr":"Bangalore","ObjName":"Testing"}]
Related
I am trying to find a match inside this JSON array but I find it a bit complicated since it's a nested array of objects.
I'm not sure what I am doing entire wrong here:
The idea is that I have an array with a set of permissions and I want to return only the set of permissions that match the role:
var data = [{
"visitor": {
"static": ["page-one:visit", "home-page:visit", "login"]
}
}, {
"users": {
"static": ["posts:list", "posts:create", "users:getSelf", "home-page:visit", "dashboard-page:visit"]
}
}, {
"admin": {
"static": ["posts:list", "posts:create", "posts:edit", "posts:delete", "users:get", "users:getSelf", "home-page:visit", "dashboard-page:visit"]
}
}]
var role = "admin"
for(var x=0;x <data.length;x++){
if(role === data[x]){
console.log("OLE, we got a match!" + data[x])
}
}
For some reason I just can't find a match. I just wanna return the full object like:
"admin":{
"static": ["posts:list", "posts:create", "posts:edit", "posts:delete", "users:get", "users:getSelf", "home-page:visit", "dashboard-page:visit"]
}
Here is a JS Bin Link.
You could use the .find function like below:
data.find(function(x){ return Object.keys(x).indexOf(role) > -1; });
Given your role is the key of the object, you need to check if the object itself contains the role as a key, for this you'd use Object.keys(<object>).indexOf(role) where indexOf will return the value of -1 if it's not found and 0+ if found.
var data = [{"visitor":{"static":["page-one:visit","home-page:visit","login"]}},{"users":{"static":["posts:list","posts:create","users:getSelf","home-page:visit","dashboard-page:visit"]}},{"admin":{"static":["posts:list","posts:create","posts:edit","posts:delete","users:get","users:getSelf","home-page:visit","dashboard-page:visit"]}}]
var role = "admin"
var admins = data.find(function(x){ return Object.keys(x).indexOf(role) > -1; });
console.log(admins);
if you wanted to accommodate for an array of different roles, you can use the following, easy to follow example.
var data = [{"visitor":{"static":["page-one:visit","home-page:visit","login"]}},{"users":{"static":["posts:list","posts:create","users:getSelf","home-page:visit","dashboard-page:visit"]}},{"admin":{"static":["posts:list","posts:create","posts:edit","posts:delete","users:get","users:getSelf","home-page:visit","dashboard-page:visit"]}}]
var role = ["admin", "visitor"];
var admins = role.map(function(role) { return getObjectsForRole(role); })
function getObjectsForRole(role)
{
return data.find(function(x){
return Object.keys(x).indexOf(role) > -1;
});
}
console.log(admins);
The above is pretty much the same as before, but we're mapping (.map) each role and calling a function which contains our call to the .find function.
This might be a silly question but I did not found any answers for it. How can I get the parent's name from this json for example ?
{
"someParentName":{
"somechild":{
"value1":"test"
}
}
}
So how can i log the "someParentName" ? Any language would be good but i am using JS.
var data = {
"someParentName":{
"somechild":{
"value1":"test"
}
}
}
var parent_key = Object.keys(data)[0]
console.log(data[parent_key]);
Right now it's not a JSON, it's already an object. That's fine. The Object.keys method will give you all the top-level property names (so, here, ["someParentName"]). Is this what you're after?
const obj = {
"someParentName": {
"somechild": {
"value1": "test"
}
}
}
console.log(Object.keys(obj));
If your object has a single key, then you can use Object.keys(obj)[0], otherwise, using Object.keys() will return an array of all keys at root level:
const obj = {
"someParentName":{
"somechild":{
"value1":"test"
}
}
}
console.log(Object.keys(obj)[0]);
Try this:
console.log(data.someParentName.somechild.value1);
where
var data = {
"someParentName":{
"somechild":{
"value1":"test"
}
}
}
there was a lot of these on stackoverflow
How to access elements of json array using javascript/jquery? [closed]
I am looking for some general advice about how I should be thinking to go about doing this.
What I need to do is take an object that has "usernames" : userId, etc.. and split them into separate objects or arrays with each object only containing usernames that start from a certain letter.
So right now I have:
allusers = {"adam292":10302, "alex92":12902, "briannv999":10302, "sandra127":11102, "sam11":100 }
but I need to split them into their own objects or arrays like the following:
ausers = { "adam292":10302, "alex92":12902 }
busers = { "briannv999":10302 }
susers = {"sandra127":11102, "sam11":1002 }
I am doing this because I need to display a dialog box that also shows the letters a - z which would be links that you can click to display users that start with that letter.
Any advice is very much appreciated!
Here is one way to do it:
Working Fiddle
looping through the object we grab the first letter and check to see if we have a key for it in our users object, if not we make one and assign an array (containing the user data) to it, if yes we push to that array:
var users = {};
for (var user in allusers) {
var firstLetter = user.slice(0,1);
if (users[firstLetter]) {
users[firstLetter].push([user, allusers[user]]);
}
else {
users[firstLetter] = [[user, allusers[user]]];
}
}
The output of the code above using your example object is the following:
{
a: [["adam292", 10302], ["alex92", 12902]],
b: [["briannv999", 10302]],
s: [["sandra127", 11102], ["sam11", 100]]
}
you can do this in a loop:
letter2users = {}
for (var uname in allusers) {
if (!letter2users[uname[0]]) {
letter2users[uname[0]] = [];
}
letter2users[uname[0]].push(allusers[uname]);
}
# access this by using letter2users.a lettersusers.b
I have a dataset of records that look like this :
[{
"d1d":"2015-05-28T00:00:00.000Z",
"d1h":0,
"d15m":0,
"ct":3
},
{
"d1d":"2015-05-28T00:00:00.000Z",
"d1h":0,
"d15m":0,
"ct":1
}
]
The ct value changes in every record. If d1d, d1h, and d15m are the same in one or more records, I need to combine those records into one with the sum of all the ct values.
I do have jquery, can I use grep for this?
I realize the server side could do a better job of getting me this data , but I have zero control over that.
You don't have to use jQuery for this, vanilla JavaScript will do.
I'll show you two solutions to your problem;
Example 1: Abusing Array#reduce as an iterator
var intermediaryArray = [];
dataset.reduce(function(prev, curr) {
if(prev.d1d === curr.d1d && prev.d1h === curr.d1h && prev.d15m === curr.d15m) {
intermediaryArray.push({
d1d: prev.d1d,
d1h: prev.d1h,
d15m: prev.d15m,
ct: prev.ct + curr.ct
});
} else {
// push the one that wasn't the same
intermediaryArray.push(curr);
}
// return current element so reduce has something to work on
// for the next iteration.
return curr;
});
Example 2: Using Array#Map and Array#Reduce in conjunction
This example utilises underscore.js to demonstrate the logic behind what you want to do.
.map() produces the new array of grouped objects.
.groupBy() produces an array of subarrays containing the objects that pass the predicate that all objects must share the same d1d or grouping function.
.reduce() boils all subarrays down to one value, your object with both cts added to each other.
var merged = _.map(_.groupBy(a, 'd1d'), function(subGroup) {
return subGroup.reduce(function(prev, curr) {
return {
d1d: prev.d1d,
d1h: prev.d1h,
d15m: prev.d15m,
ct: prev.ct + curr.ct
};
});
});
Here's one possible solution:
var dataset = [{
"d1d":"2015-05-28T00:00:00.000Z",
"d1h":0,
"d15m":0,
"ct":3
},
{
"d1d":"2015-05-28T00:00:00.000Z",
"d1h":0,
"d15m":0,
"ct":1
}
]
function addCt(dataset) {
var ctMap = {}
var d1d, d1h, d15m, ct, key, value
for (var ii=0, record; record=dataset[ii]; ii++) {
key = record.d1d+"|"+record.d1h+"|"+record.d15m
value = ctMap[key]
if (!value) {
value = 0
}
value += record.ct
ctMap[key] = value
}
return ctMap
}
ctMap = addCt(dataset)
console.log(ctMap)
// { "2015-05-28T00:00:00.000Z|0|0": 4 }
You may want to construct the key in a different way. You may want set the value to an object containing the d1d, d1h, d15m and cumulated ct values, with a single object for all matching d1d, d1h and d15m values.
I have the following JSON -
{
"node1":[
{
"one":"foo",
"two":"foo",
"three":"foo",
"four":"foo"
},
{
"one":"bar",
"two":"bar",
"three":"bar",
"four":"bar"
},
{
"one":"foo",
"two":"foo",
"three":"foo",
"four":"foo"
}
],
"node2":[
{
"link":"baz",
"link2":"baz"
},
{
"link":"baz",
"link2":"baz"
},
{
"link":"qux",
"link2":"qux"
},
]
};
I have the following javascript that will remove duplicates from the node1 section -
function groupBy(items, propertyName) {
var result = [];
$.each(items, function (index, item) {
if ($.inArray(item[propertyName], result) == -1) {
result.push(item[propertyName]);
}
});
return result;
}
groupBy(catalog.node1, 'one');
However this does not account for dupicates in node2.
The resulting JSON I require is to look like -
{
"node1":[
{
"one":"foo",
"two":"foo",
"three":"foo",
"four":"foo"
},
{
"one":"bar",
"two":"bar",
"three":"bar",
"four":"bar"
}
],
"node2":[
{
"link":"baz",
"link2":"baz"
},
{
"link":"qux",
"link2":"qux"
},
]
};
However I cannot get this to work and groupBy only returns a string with the duplicates removed not a restructured JSON?
You should probably look for some good implementation of a JavaScript set and use that to represent your node objects. The set data structure would ensure that you only keep unique items.
On the other hand, you may try to write your own dedup algorithm. This is one example
function dedup(data, equals){
if(data.length > 1){
return data.reduce(function(set, item){
var alreadyExist = set.some(function(unique){
return equals(unique, item);
});
if(!alreadyExist){
set.push(item)
}
return set;
},[]);
}
return [].concat(data);
}
Unfortunately, the performance of this algorithm is not too good, I think somewhat like O(n^2/2) since I check the set of unique items every time to verify if a given item exists. This won't be a big deal if your structure is really that small. But at any rate, this is where a hash-based or a tree-based algorithm would probably be better.
You can also see that I have abstracted away the definition of what is "equal". So you can provide that in a secondary function. Most likely the use of JSON.stringify is a bad idea because it takes time to serialize an object. If you can write your own customized algorithm to compare key by key that'd be probably better.
So, a naive (not recommended) implementation of equals could be somewhat like the proposed in the other answer:
var equals = function(left, right){
return JSON.stringify(left) === JSON.stringify(right);
};
And then you could simply do:
var res = Object.keys(source).reduce(function(res, key){
res[key] = dedup(source[key], equals);
return res;
},{});
Here is my version:
var obj = {} // JSON object provided in the post.
var result = Object.keys(obj);
var test = result.map(function(o){
obj[o] = obj[o].reduce(function(a,c){
if (!a.some(function(item){
return JSON.stringify(item) === JSON.stringify(c); })){
a.push(c);
}
return a;
},[]); return obj[o]; });
console.log(obj);//outputs the expected result
Using Array.prototype.reduce along with Array.prototype.some I searched for all the items being added into the new array generated into Array.prototype.reduce in the var named a by doing:
a.some(function(item){ return JSON.stringify(item) === JSON.stringify(c); })
Array.prototype.some will loop trough this new array and compare the existing items against the new item c using JSON.stringify.
Try this:
var duplicatedDataArray = [];
var DuplicatedArray = [];
//Avoiding Duplicate in Array Datas
var givenData = {givenDataForDuplication : givenArray};
$.each(givenData.givenDataForDuplication, function (index, value) {
if ($.inArray(value.ItemName, duplicatedDataArray) == -1) {
duplicatedDataArray.push(value.ItemName);
DuplicatedArray.push(value);
}
});