473,405 Members | 2,154 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

merge JSON structures

Is there a function or library somewhere that merges 2 JSON data
structures? For instance this:

{ "one": [1,3] }

plus

{ "one": [2] }

equals

{ "one": [1,2,3] }

Nov 13 '06 #1
15 9016


On 13 Nov., 05:43, hobosales...@gmail.com wrote:
Is there a function or library somewhere that merges 2 JSON data
structures? For instance this:

{ "one": [1,3] }

plus

{ "one": [2] }

equals

{ "one": [1,2,3] }
This is a very special case. In prototype library you find
Object.extend(), but it overwrites same keys. You need a special
funcion that concats Arrays key for key (if the key holds an array),
e.g.

Object.plus = function(obj1, obj2) {
var res = {};
// "copy" obj1 keys to new object res
Object.extend(res, obj1);
// now overwrite obj1 keys in res by contents of obj2
Object.extend(res, obj2);
// now consider overwritten obj 1 keys one by one, like in example -
only arrays
for(var key in obj1) {
if (obj1[key] instanceof Array)
// concatenate Arrays, don't sort them like in your example
res[key] = obj1[key].concat(res[key]);
}
}

I hope I could help you, for Object.extend look in
http://script.aculo.us/prototype.js

Andi

Nov 13 '06 #2
And return the result:

Object.plus = function(obj1, obj2) {
...
return res;
}

Nov 13 '06 #3
ho**********@gmail.com wrote:
Is there a function or library somewhere that merges 2 JSON data
structures? For instance this:

{ "one": [1,3] }

plus

{ "one": [2] }

equals

{ "one": [1,2,3] }
If you are specifically after the above structure, then the following
should do the trick:

<script type="text/javascript" src="json.js"></script>
<script type="text/javascript">

var jsonStr1 = '{ "one": [1,3] }';
var jsonStr2 = '{ "one": [2],'
+ ' "two": [1]}';

function jsonAdd(str1, str2){
var obj1 = eval('(' + str1 + ')');
var obj2 = eval('(' + str2 + ')');
for (var prop in obj2){
if (obj2[prop] instanceof Array){
if (prop in obj1){
obj1[prop] = obj1[prop].concat(obj2[prop]);
} else {
obj1[prop] = obj2[prop].concat();
}
}
}
return obj1.toJSONString();
}

alert( jsonAdd(jsonStr1, jsonStr2) );

</script>

where json.js can be found at: <URL: http://www.json.org/json.js >. If
you don't want to extend the Array prototype (and therefore could
remove the instanceof Array test), there is a functionalised version
that is no longer available from json.org - it has been posted here:
<URL:
http://groups.google.com.au/group/ru...43fb9e0b2f5a3d
>

--
Rob

Nov 13 '06 #4
webEater wrote:
This is a very special case. In prototype library you find
Object.extend(), but it overwrites same keys. You need a special
funcion that concats Arrays key for key (if the key holds an array),
It gets more complicated because { "this":"that" } is an object with no
concat method. So from what I can tell I need to write my own function
that looks at typeof and the constructor property to tell if I have an
array, object, or something else, and either concat, straight assign,
or loop through object properties and assign. Yuck, oh well.

I'm sure someone has done this before, I've never been into javascript,
there isn't anything like CPAN or PEAR for JS is there? All these "free
DHTML scripts!" web sites sure don't cut it.

HS

Nov 13 '06 #5
RobG wrote:
If you are specifically after the above structure
Nope, I'm after a big complicated structure that'll probably get bigger
and more complicated later. But thanks!
where json.js can be found at: <URL: http://www.json.org/json.js >. If
Thanks for that link.

HS

Nov 13 '06 #6

ho**********@gmail.com wrote:
RobG wrote:
If you are specifically after the above structure

Nope, I'm after a big complicated structure that'll probably get bigger
and more complicated later. But thanks!
Presumably you are only going to "join" properties with the same name
and type. The concept of your "join" only makes sense for Array or
String objects, I've shown an Array concat, adding a String concat
would be trivial.

What will you do with properties that are Boolean or Number (guessing
that Undefined and Null are irrelevant)?
--
Rob

Nov 13 '06 #7
RobG wrote:
Presumably you are only going to "join" properties with the same name
and type. The concept of your "join" only makes sense for Array or
String objects, I've shown an Array concat, adding a String concat
would be trivial.
Well I've kicked this idea around my head for the last day or two, and
I think it's more complex than it seems at first glance. I have a
server generated config structure that I want to be merged with a
hardcoded default JS structure, but I don't want it to obliterate
nested config variables just because they weren't defined on the
server.

I'll call this function mergeJSON(arg1, arg2), take one structure and
copy it into another, overwriting values that exist, but making sure
not to lose any data unless necessary. For instance:

ret = mergeJSON( [ {"one": 1} ], [ {"one": 2} ] )

If we just looked at each argument's constructor, saw an array, and did
arg1.concat(arg2), we'd get:

[ {"one": 1}, {"one": 2} ]

But I want to look at ret[0].one and find the value defined in arg1, or
if it doesn't exist the value defined in arg2. In other words, I want
this:

[ {"one": 1} ]

So it's not as simple as it seems on the surface I think. It has to
recurse through each level of the hierarchy, working down to "leaf
nodes", merging everything manually rather than using concat.
What will you do with properties that are Boolean or Number (guessing
Overwrite arg2 if they exist in both.
that Undefined and Null are irrelevant)?
If undefined don't overwrite any data, but null is defined, so
overwrite just like a bool, number, string. I could concat strings but
it doesn't work in the context I need it. It would be trivial to concat
strings when a flag is passed though.

I'll post what I come up with if anyone's interested, in the meantime I
welcome feedback.

HS

Nov 14 '06 #8
Stupid javascript doesn't pass by reference and keeps saying "too much
recursion". I want a real language. Maybe I can send it back to the
server with ajax and use perl. I have no idea how to get around the
"too much recursion", it says that even when only recursing once with a
single element array. Without recursion it becomes ugly and limited.
What's this no recursion thing? Surely javascript allows recursive
functions?

HS

Nov 14 '06 #9
ho**********@gmail.com wrote:
Stupid javascript doesn't pass by reference
Sure it does, except for primitives.
and keeps saying "too much
recursion".
Then you have probably written bad code ;)
I want a real language.
s/I want a real language/I want a language that acts how I expect it to, not
how it's defined/
I have no idea how to get around the
"too much recursion", it says that even when only recursing once with
a single element array.
Then something is wrong.

It seems that you want some behavior that "makes sense", but you don't
really know what that is. Merging of data structures isn't as simple as you
might think.

First, write down requirements. How _exactly_ do you want the merge to
behave? When merging objects with common properties, which should get
priority? Should non-null values always overwrite null values? How should
arrays be treated? What about cases like
{x:1} and {x:[1]} ? What about {x:[1,2]} and {x:[2,1]} ?

Before you can write code, you need to clearly understand what you want. At
that point, people here can help you in tweaking the code you create.

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
Nov 14 '06 #10
Matt Kruse wrote:
ho**********@gmail.com wrote:
Stupid javascript doesn't pass by reference

Sure it does, except for primitives.
and keeps saying "too much
recursion".

Then you have probably written bad code ;)
<snip>

Erroneous code at minimum. As I recall (and it was a while ago now)
testing how much recursion prompted the "too much recursion" warning
came up with a figure of around 10,000 recursive calls.

Richard.

Nov 14 '06 #11
ho**********@gmail.com said the following on 11/14/2006 5:22 AM:
Stupid javascript doesn't pass by reference and keeps saying "too much
recursion". I want a real language. Maybe I can send it back to the
server with ajax and use perl.
And then you have to deal with "Stupid javascript" to be able to use
ajax to send it to the server. And if recursion is giving you a
headache, I want to be your supplier of headache medicine when you get
to the XMLHTTPRequest Object.

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Nov 14 '06 #12
Matt Kruse wrote:
ho**********@gmail.com wrote:
Stupid javascript doesn't pass by reference

Sure it does, except for primitives.
I thought I would have to test for type to find out if I'm passing a
reference or not, something that javascript seems to suck at, but I
don't think I do.
s/I want a real language/I want a language that acts how I expect it to, not
how it's defined/
Yeah, basically. Another translation would be "Boo hoo I'm not as
comfortable writing JS as with other languages I've used 1000 times
more often...".
and keeps saying "too much
recursion".

Then you have probably written bad code ;)
I think so. It was late and I don't even remember what I wrote, but I
don't have that problem now.
First, write down requirements. How _exactly_ do you want the merge to
behave? When merging objects with common properties, which should get
priority? Should non-null values always overwrite null values? How should
arrays be treated? What about cases like
{x:1} and {x:[1]} ? What about {x:[1,2]} and {x:[2,1]} ?

Before you can write code, you need to clearly understand what you want. At
that point, people here can help you in tweaking the code you create.
I have my requirements very clear in my head, I don't think I'm very
good at communicating them on usenet though. I think I have what I want
here (I hope line wraps don't ruin this, please point out the best way
to post code if I screwed up):

function merge_json(merger, mergee) {
if (merger.constructor.toString().indexOf("Array") == -1 &&
merger.constructor.toString().indexOf("Object") == -1) {
//must have been passed non-JSON
return false;
}
for (i in merger) {
if (mergee[i]) {
if ((merger[i].constructor.toString().indexOf("Array") == -1 &&
merger[i].constructor.toString().indexOf("Object") == -1) ||
(mergee[i].constructor.toString().indexOf("Array") == -1 &&
mergee[i].constructor.toString().indexOf("Object") == -1)) {
//one or the other isn't an array/object
mergee[i] = merger[i];
} else {
merge_json(merger[i], mergee[i]);
}
} else {
mergee[i] = merger[i];
}
}
return true;
}

It seems to work, the super ugly if statements notwithstanding.

HS

Nov 14 '06 #13
Randy Webb wrote:
And then you have to deal with "Stupid javascript" to be able to use
ajax to send it to the server. And if recursion is giving you a
I was kidding, but wouldn't it be nice to run perl in the browser?
Unless you're a user that cares about "security" or things like that.

HS

Nov 14 '06 #14
ho**********@gmail.com wrote:
>s/I want a real language/I want a language that acts how I expect it
to, not how it's defined/
Yeah, basically. Another translation would be "Boo hoo I'm not as
comfortable writing JS as with other languages I've used 1000 times
more often...".
Indeed, javascript has the ability to frustrate and confuse new users. But
it's not as bad as VBScript! (IMO).

I didn't check your code functionality or run any tests with it, but I
thought I would share a few comments:
if (merger.constructor.toString().indexOf("Array") == -1 &&
merger.constructor.toString().indexOf("Object") == -1) {
This is not robust, is it? What if I pass in an instance of Car, which is an
Object?
if (mergee[i]) {
if mergee[i] has a value of false or 0, this will be false and it won't be
evaluated.
Instead you want
if (typeof mergee[i]!="undefined") {

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
Nov 14 '06 #15
VK

ho**********@gmail.com wrote:
I have my requirements very clear in my head, I don't think I'm very
good at communicating them on usenet though. I think I have what I want
here (I hope line wraps don't ruin this, please point out the best way
to post code if I screwed up):

function merge_json(merger, mergee) {
if (merger.constructor.toString().indexOf("Array") == -1 &&
merger.constructor.toString().indexOf("Object") == -1) {
//must have been passed non-JSON
return false;
}
for (i in merger) {
if (mergee[i]) {
if ((merger[i].constructor.toString().indexOf("Array") == -1 &&
merger[i].constructor.toString().indexOf("Object") == -1) ||
(mergee[i].constructor.toString().indexOf("Array") == -1 &&
mergee[i].constructor.toString().indexOf("Object") == -1)) {
//one or the other isn't an array/object
mergee[i] = merger[i];
} else {
merge_json(merger[i], mergee[i]);
}
} else {
mergee[i] = merger[i];
}
}
return true;
}
So brute force speaking you want to implement a throughout exclusive
disjunction between the default JSON structure and the server-updated
JSON structure.
Two questions then (the default structure shall be called "Default" to
the rest of this document, the server-updated structure shall be called
"Updater" to the rest of this document):

1) Is it guaranteed that both Default and Updater are homostructural?
Other words, is it guaranteed that wherever Default has Object, Updater
has Object, wherever Default has Array, Updater has Array; so it cannot
be that on Object leaf of Default we may have the matching Array leaf
of Updated?

2) Do we have ... I almost wrote "homosetual" ... San Francisco
influence :-)... do we have matching array sizes and property sets in
Default and Updater? So say if a leaf in Default is Array, then Updater
will have the same number of elements (but possibly with other values
in some elements) And if we have an Object whan it will be possibly
different property values but the same property set?

Nov 14 '06 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
by: G Matthew J | last post by:
http://htmatters.net/htm/1/2005/07/evaling-JSON.cfm This is more or less in response to Mr Crockford's admonition a few months ago, "fork if you must". Ironically, although in that usenet post...
20
by: Luke Matuszewski | last post by:
Welcome As suggested i looked into JSON project and was amazed but... What about cyclical data structures - anybody was faced it in some project ? Is there any satisactional recomendation... ...
9
by: anunaygupta | last post by:
Hello all, I have a data structures problem. Assume there are 2 linked lists L1 and L2. They merge into some node. L1 1->2->3->4->5->6 / L2 8->7->9->/ L1 and L2 merge in node with value...
10
by: Frank Millman | last post by:
Hi all I am writing a multi-user accounting/business application, which uses sockets to communicate between server and client. The server contains all the business logic. It has no direct...
23
by: dhtmlkitchen | last post by:
JSON We all know what it is. In ECMAScript 4, there's a JSON proposal: Object.prototype.toJSONString String.prototype.parseJSON The current proposal, String.prototype.parseJSON, returns...
3
by: skbach | last post by:
I have the following relatively simple requirement: I have 2 JSON strings, which contains varying nested objects. I need to merge the two strings into one string, maintaining all the hierarchies....
6
by: Lasse Reichstein Nielsen | last post by:
Max <adsl@tiscali.itwrites: Not really. It shows that a particularly naïve implementation of a conversion from XML to JSON doesn't work well. What if the conversion of <e> some
5
by: maya | last post by:
(function() { function initProductImagePanels() { var elements = YAHOO.util.Dom.getElementsByClassName('productImage', 'img'); for(var i = 0; i < elements.length; i++) { var el = new...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.