I want to merge two object using JavaScript
First
{
"user" : " Hari",
"friend" : "Shiva",
"friendList": ["Hanks"," Tom"," Karma"," Hari"," Dinesh"]
}
second
{
"user" : "Hari",
"friend" : " Shiva",
"friendList" : ["Karma"," Tom"," Ram"," Bindu"," Shiva",
" Kishna"," Bikash"," Bakshi"," Dinesh"]
}
and form a single object:
expected output
{
"user" : "Hari"
"friend" : "Shiva",
"friendList":[
["Hanks"," Tom","Karma"," Hari"," Dinesh"],
["Karma"," Tom"," Ram"," Bindu"," Shiva"," Kishna"," Bikash"," Bakshi"," Dinesh"]
]
}
Is it possible? I am sorry if it is wrong question....but I need to solve in this way and I do not have much idea about JavaScript.
You can add from one array to anther like this
var a={
"user" : " Hari",
"friend" : "Shiva",
"friendList": ["Hanks"," Tom"," Karma"," Hari"," Dinesh"]
};
var b={
"user" : "Hari",
"friend" : " Shiva",
"friendList" : ["Karma"," Tom"," Ram"," Bindu"," Shiva",
" Kishna"," Bikash"," Bakshi"," Dinesh"]
};
b.friendList.concat(a.friendList);
you will get on b all the array of a+b...
you will not get this structure that you want. For my code you will get an array of strings from a and b, if you want this structure you need to change the result to be an object and not array.
also can see example from : link
The following code will merge the objects as described in your question:
var firstObject = {
"user" : " Hari",
"friend" : "Shiva",
"friendList": ["Hanks"," Tom"," Karma"," Hari"," Dinesh"]
};
var secondObject = {
"user" : "Hari",
"friend" : " Shiva",
"friendList" : ["Karma"," Tom"," Ram"," Bindu"," Shiva",
" Kishna"," Bikash"," Bakshi"," Dinesh"],
};
function mergeMyObjectsIntoNew(first,second,copyFriendListArrayReference){
//.trim() is needed in the compare here because example data has a leading space
// in secondObject.friend
if(first.user.trim() === second.user.trim()
&& first.friend.trim() === second.friend.trim()){
var newObject={}; //The new object
newObject.user = first.user;
newObject.friend = first.friend;
newObject.friendList = []; //Create new array
if(copyFriendListArrayReference){
//This copies references for the arrays in first.friendList and
// second.friendList into the array new.friendList. These will be the
// same arrays as exists in first and second. Changes to the contents
// of those arrays will affect the arrays in the newObject.
newObject.friendList[0] = first.friendList; //add friendList from first
newObject.friendList[1] = second.friendList; //add friendList from second
}else{
//This copies the string contents of the arrays in first.friendList and
// second.friendList into the array new.friendList. These will NOT be the
// same arrays as exists in first and second. Changes to the contents
// of those arrays will NOT affect the arrays in the newObject.
// This is the default behavior.
//Copy contents of friendList from first
newObject.friendList[0] = Array.from(first.friendList);
//Copy contents of friendList from second
newObject.friendList[1] = Array.from(second.friendList);
}
return newObject;
}//implicit else due to 'return' in all if paths
return null; //Indicate to caller that there was not a match.
}
//Get new merged object with copy of friendList
mergedObject = mergeMyObjectsIntoNew(firstObject,secondObject);
console.log(mergedObject);
Comments
Using multiple very similarly structured objects is, often, a bad idea
It is, generally, not a good idea to use objects that have two different structures, unless you are keeping those objects distinctly separate. When you do have multiple structures for objects which you treat similarly (i.e. you use the same functions/methods to manipulate objects with both structures), all of your code has to account for each of the multiple structures. This can rapidly make your code much more complex and, potentially, more confusing than it would need to be if you did not have multiple structures for objects which you treat similarly.
In this case, you are wanting your result object to have a friendList property which is an array of arrays of strings whereas your source objects have a friendList property which is an array of strings. If you are going to use mergeMyObjectsIntoNew on both object structures, having the two different structures for the friendList property would require more logic in mergeMyObjectsIntoNew, if you want it to be able to operate on both types of object with the results you would, probably, expect.
For instance, the following code will not produce the result that you are probably expecting:
mergedFirstSecondObject = mergeMyObjectsIntoNew(firstObject,secondObject);
mergedthirdFourthObject = mergeMyObjectsIntoNew(firstObject,secondObject);
mergedFourObjects = mergeMyObjectsIntoNew(mergedFirstSecondObject,mergedthirdFourthObject);
This will produce an object that has a friendList property that is an array of arrays of arrays of strings. The mergedFourObjects object is structured like:
{
"user" : " Hari",
"friend" : "Shiva",
"friendList": [
[
friendListArrayFromFirstObject,
friendListArrayFromSecondObject
],
[
friendListArrayFromThirdObject,
friendListArrayFromFourthObject
]
]
}
In your case, you are probably better off picking to always have the friendList property be only one or the other of an array of array of strings, or an array of strings. Having the friendList property such that it might be either structure will significantly complicate your code everywhere you use these objects.
Using a class would be the better approach to handling your objects
If you are going to be using your objects in a larger project, it is probably a better idea to use a class for the object. This would allow you to move things like comparing the objects and merging the objects into methods of the class (e.g. MyObject.prototype.compare(second) and MyObject.prototype.merge(second). However, that is a discussion well beyond the scope of your question. If you want more information, I suggest you search for information about using object classes in JavaScript.
Related
I have an HTML page that contains a stringified JSON object. The object has this structure:
{
"x":{
"key1":[],
"key2":{},
"keyN":{},
"myKey":{
"randomID238492":{
"items":[
{ "value":"zzzz" },
{ "value":"aaaa" },
{ ...}
]
}
}
}
}
I want to replace this object with one in which the "items" array has been sorted. Here is what I will and won't know about the object:
"myKey" and "items" will always be the relevant object keys
"myKey" will contain only one random ID, and the "items" key will always be its first child
I won't know the order of "myKey" in the object.
I won't know the true randomID under which "items" nests.
Is there a clear, efficient way to replace this JSON object with one in which "items" has been sorted? Right now, I do it by using this jQuery function after the page has rendered:
$(function() {
var myData = $( "#myJSON_string" )[0]; // <script> node that contains the string
var myDataJSON = JSON.parse(myData.innerText); // JSON string
var myKeyJSON = myDataJSON["x"]["myKey"]; // object
var myArr = myKeyJSON[Object.keys(myKeyJSON)[0]]["items"]; // array to sort
// Now sort and revise. I'm leaving myCompare() out of the example for brevity
myKeyJSON[Object.keys(myKeyJSON)[0]]["items"] = myArr.sort(myCompare);
myDataJSON["x"]["myKey"] = myKeyJSON;
myDataJSON = JSON.stringify(myDataJSON);
myData.innerText = myDataJSON;
});
This approach works, but it seems rather labored. It might be better, for example, if I could revise the JSON object "in place" without parsing it and then re-stringifying it.
Many SO posts, like this one, speak to the general question of how to sort a JSON array. But I can't see that any speak to the specific question posed here.
I get this error message when I want to add playerrewards to ItemIds. The property ItemIds is List. What is wrong?
"errorDetails": {
"ItemIds": [
"invalid item at index 0: The ItemIds field is required."
]
}
In this case, I want to add 2 different strings to ItemIds, but sometimes the amount changes and I will need to add a different amount of strings to ItemIds. playerrewards is not always just 2 strings, for example in another case playerrewards could consist of 10 different strings that I need to add to ItemIds.
How can I add playerrewards to the property ItemIds?
var playerrewards = [];
playerrewards.push("ItemTitaniumSword");
playerrewards.push("ItemBambooSword");
var result = server.GrantItemsToUser(
{
PlayFabID: currentPlayerId,
CatalogVersion : "New Shop",
ItemIds : [playerrewards]
});
you can try assigning the value directly as playerrewards is a variable now
var playerrewards = [];
playerrewards.push("ItemTitaniumSword");
playerrewards.push("ItemBambooSword");
var result = server.GrantItemsToUser(
{
PlayFabID: currentPlayerId,
CatalogVersion : "New Shop",
ItemIds : playerrewards
});
In your example you trying to store one array inside another one.
{...
ItemIds : [/*playerrewards is [Array]*/]
}
As I understand there are two solutions:
First is to store playerrewards directly, and it will be like this
{...
ItemIds : playerrewards
}
Second is to use spread operator, it will bring you a possibility to merge previous state of playerrewards with new one without any extra methods as push and etc.
{...
ItemIds : [...playerrewards]
}
What's using better for the task is up to you =)
I have an associative array here -
var dataset = {
"person" : [
{"userLabels": ["Name","Role"]},
{"tagNames": ["lName","role"]},
{"tableClass": "width530"},
{"colWidths": ["50%","50%"]}
]
}
I tried accessing the 'userLabels' object using jQuery using various methods but I failed. I think I am doing something wrong with basics. I want the userLabels object to be accessed using jQuery and the result should be an array, so I can perform the jQuery.inArray() operation.
Firstly, here's how you can access dataset using the method you have.
var dataset =
{
"person" : [
{"userLabels": ["Name","Role"]},
{"tagNames": ["lName","role"]},
{"tableClass": "width530"},
{"colWidths": ["50%","50%"]}
]
};
alert(dataset['person'][0]['userLabels']); //style 1
alert(dataset.person[0]['userLabels']); //style 2
alert(dataset.person[0].userLabels); //style 3
//Also you can use variables in place of specifying the names as well i.e.
var propName ='userLabels';
alert(dataset.person[0][propName]);
//What follows is how to search if a value is in the array 'userLabels'
$.inArray('Name', dataset.person[0].userLabels);
I'd like to ask why you're doing this in a such an 'interesting way'. Why don't you just make them all objects?
That's what I would do if I were you because if you think about it, a person IS an object and it should be noted that arrays are basically objects in Javascript with a 'length' property, though I won't elaborate on it here (feel free to do some research though). I'm guessing it's because you don't know how to iterate over object properties. Of course if it makes more sense to you, go for it.
Note one of the differences between an array and an object is that object properties need to be defined; you'll notice that I gave 'Name' and 'Role' values of 'undefined' below.
In any case, here is what I would do:
var dataset =
{
"person" : {
"userLabels": {"Name" : undefined,"Role": undefined},
"tagNames": {"lName" : undefined,"role" : undefined},
"tableClass": "width530",
"colWidths": ["50%","50%"]
}
};
for (var i in dataset) { //iterate over all the objects in dataset
console.log(dataset[i]); //I prefer to use console.log() to write but it's only in firefox
alert(dataset[i]); // works in IE.
}
//By using an object all you need to do is:
dataset.person.userLabels.hasOwnProperty('Role'); //returns true or false
Anyways, hope this helps.
var basic = dataset.person[0].userLabels;
// | | |
// | | --- first element = target object
// | --- person property
// ---- main-object
var userLabels = dataset.person[0].userLabels;
if ($.inArray(yourVal, userLabels) !== -1) {
doStuff();
}
var profileDataCalls = [];
profileDataCalls['Profile'] = GetUserAttributesWithDataByGroup;
profileDataCalls['Address'] = GetUserAddresses;
profileDataCalls['Phone'] = GetUserPhoneNumbers;
profileDataCalls['Certs'] = GetUserCertifications;
profileDataCalls['Licenses'] = GetUserLicenses;
profileDataCalls['Notes'] = GetUserNotes;
My problem is the above JavaScript array is only a length of 0. I need an array that can be iterated over and holds the key(string) and value?
You want:
var profileDataCalls = {
'Profile' : GetUserAttributesWithDataByGroup,
'Address' : GetUserAddresses,
'Phone' : GetUserPhoneNumbers,
'Certs' : GetUserCertifications,
'Licenses' :GetUserLicenses,
'Notes' : GetUserNotes
};
Then you can access the values with, for example, profileDataCalls.profile or profileDataCalls[profile] (to retrieve whatever value is represented by the variable GetUserAttributesWithDataByGroup)
To iterate through the object, use:
for (var property in profileDataCalls) {
if (profileDataCalls.hasOwnProperty(property)) {
console.log(property + ': ' + profileDataCalls[property));
}
}
Javascript doesnt have associative arrays per say , what you are doing is adding properties to the Array instance. IE doint something like
profileDataCalls.Notes = GetUserNotes;
so you cant really use length to know how many properties your array would have.
now if your issue is iterating over your object properties , you dont need an array , just use an object :
profileDataCalls = {}
then use a for in loop to iterate over the keys :
for(var i in profileDataCalls ){
// i is a key as a string
if(profileDataCalls.hasOwnProperty(i)){
//do something with profileDataCalls[i] value , or i the key
}
}
it you have different requirements then explain it.
now the tricky part is profileDataCalls[0]="something" would be valid for an object({}), you would create a property only available through the lookup (obj[0]) syntax since it is not a valid variable name for javascript.
other "crazy stuffs" :
o={}
o[0xFFF]="foo"
// gives something like Object {4095:"foo"} in the console
Actually it also works like this:
var profileDataCalls = [{
Profile: GetUserAttributesWithDataByGroup(),
Address: GetUserAddresses(),
Phone: GetUserPhoneNumbers(),
Certs: GetUserCertifications(),
Licenses: GetUserLicenses(),
Notes: GetUserNotes()
}];
Then you can access the values with, for example, profileDataCalls[0].profile or profileDataCalls[0]["profile"].
To iterate through the object, you can use:
for (key in profileDataCalls[0]) {
console.log(profileDataCalls[0][key]);
}
Since this is an associative array, I never understood why people are saying its not possible in Javascript...in JS, everything is possible.
Even more, you could expand this array easily like this:
var profileDataCalls = [{
Profile: GetUserAttributesWithDataByGroup(),
Address: GetUserAddresses(),
Phone: GetUserPhoneNumbers(),
Certs: GetUserCertifications(),
Licenses:GetUserLicenses(),
Notes: GetUserNotes()
}{
Profile: GetUserAttributesWithDataByGroup(),
Address: GetUserAddresses(),
Phone: GetUserPhoneNumbers(),
Certs: GetUserCertifications(),
Licenses: GetUserLicenses(),
Notes: GetUserNotes()
}];
And access the array entries with profileDataCalls[0]["profile"] or profileDataCalls[1]["profile"] respectively.
What you want is an object:
Try
var profileDataCalls = new Object();
then reference your data as you do already.
I have a very large json like :
raw_obj= {"001" : {....}, "002" : {....}};
and I have an another json object which is just returned from server :
search_result = {["001", "005", "123"]};
I want to do something like
$.each(search_result, function(i,val){
alert(raw_obj.search_result[i]);
});
Is it possible? I don't want to loop through those 2 objects because in practical, there will be have around 2000 elements in a "raw_json". Which means the worst case is 2000x2000 times loop per one query.
var raw_obj= {"001" : {'...'}, "002" : {'...'}};
var search_results = ["001", "005", "123"]; // just an array
$.each(search_results, function(i, result) {
alert(raw_obj[result]);
});
The search results are an array (ie, list), not an object (ie, map) and so the syntax should be modified as above. If you have no control over the server response, use string parsing to build a new array.