How to translate a string to object notation - javascript

I'm working with a JSON validator that checks a give JSON object against a schema and returns errors if it doesn't match. One of the things I need to do is add missing attributes, but these could potentially be quite deep in the structure. The validator error returns the location of a missing attribute as a string in this format:
'data.thing1.thing2.thingN'
I can strip out the "data." bit easily enough, but I don't know how to translate the rest to correct object notation, in any depth. This is what I've got so far:
var attributeLineage = newField.split(".");
obj[attributeLineage[0]][attributeLineage[1]] = "";
So obviously this only works when there are only two levels of depth. I need to loop through the values in attributeLineage and link them all together to correctly construct the missing attribute in the given object, at any depth. How can this be done?
I might be missing something totally obvious, or going about it the wrong way, but I'm not sure how to proceed.

Using reduce() method get the reference of the inner object and update the property using last element in split array.
var newField = 'data.thing1.thing2.thingN';
// split the string
var attributeLineage = newField.split("."),
// get last element and remove it from splitted array
prop = attributeLineage.pop();
var ob = {
data: {}
};
// get the object reference
var obj = attributeLineage.reduce(function(o, k) {
// return if nested object is defined
// else define and return it
return o[k] || (o[k] = {}) && o[k];
}, ob);
// update the inner object property
obj[prop] = "hi";
console.log(ob);

Related

whats the logical explanation of [0]? [duplicate]

I'm debugging code that someone else wrote and can not figure out what they had in mind.
At the end of method there is a return statement shown below
return params[name] || null;
If params is an object (it is in this case) then
params.name
or
params['name'] would return the value of that function(method)
Two things are a mystery. In the docboc, the author stated that it this method would return a string. Clearly, it does not.
Secondly, since it is returning an object, how would I properly reference that value?
(Note: I do NOT know what the key is before hand)
Square brackets in JavaScript allow you to access Objects and Arrays by index. For an example this would be a base 0 integer for Arrays, e.g. someArray[0]. For objects this would be the key, e.g. someObject[‘key’].
Your statement return params[name] || null is looking for params (array / obj) and name (index / key)
So if your params for example is an object and name is the variable for the keys.
and you need to get its value, you would do params[name] . since name is not under quotations I am assuming its a var defined somewhere
Square Brackets ([]) allows you to access properties of any object or element of an array at a specific index
for example :
const obj = {a:true};
then obj['a'] will return true;
Or const arr = ['hello','world'];
then arr[0] will return 'hello';

How can google DataLayer be converted into javascript object with key values for variables?

When you use Google Analytics DataLayer on your website you have it as a global variable dataLayer.
You can add your own events variables into it.
How can you convert all variables inside it to an object like
{var:value}
You access it like any other object:
var dataLayer = [{
myVar1: 'val1',
myVar2: 'val2
}]
var myVar1 = dataLayer[0].myVar1;
var myVar2 = dataLayer[0].myVar2;
I do not quite understand your heated response to nyuens answer. Firstly, since this is javascript so an array is also an object, secondly the dataLayer is an array of objects or, as we call it in JavaScript, an object (it's called JavaScript Object Notation after all). So you have an array with numeric indexes where every element is an object (which might in turn contain other arrays and objects).
I strongly disagress with nyuen's suggestion to adress elements in the dataLayer with the numeric index, though. If you push data to your dataLayer before the tag manager code dataLayer[0] will contain your custom data, if you don't it will contain the gtm.load event and related data. So this is not reliable.
However it seems want you really want is to flatten the object, i.e. remove the nested structure with numerical keys and have a one-dimensional structure. Luckily somebody has written a function that does this:
var flattenObject = function(ob) {
var toReturn = {};
for (var i in ob) {
if (!ob.hasOwnProperty(i)) continue;
if ((typeof ob[i]) == 'object') {
var flatObject = flattenObject(ob[i]);
for (var x in flatObject) {
if (!flatObject.hasOwnProperty(x)) continue;
toReturn[i + '.' + x] = flatObject[x];
}
} else {
toReturn[i] = ob[i];
}
}
return toReturn;
};
This makes a "one-dimensional" object from a nested object. Usually this would mean that keys with the same name will be overwritten by the respective last element. I.e.
dataLayer = [
{'key':value1},
{'key':value2},
]
would result in a simple
{'key':value2}
since the second "key" overwrites the first. However the function above mitigates this by storing the index as part of the key name, so you would get
{'0.key':value1, '1.key':value2}
which somewhat unfortunately means you cannot use dot syntax and have to adress the elements with angled brackets:
yourvariablename['0.key']

Evaluate if Variable Name is equals to String

I have
var myArrayVariable1 = new Array();
var myStringVariable1 = 'myArrayVariable1';
var myStringVariable2 = 'myArrayVariable2';
Is there any way to figure out if one of the strings match the variables name? In case above, myStringVariable1.Value = myArrayVariable1.VariablesName
My conundrum:
I have around 100 objects that are unique to each user.
I need to update each object each minute
Each object is named as the database id; javascript would have to locate the object, delete it and then re-create it using new values (these are pulled via json)
So I need to locate the object (using the string that I have gotten from the json), then I need somehow call that object to delete it...
kind of stuck here.
In abstract I am looking for something like this:
foreach(object obj in allObjects){
if (obj.ActualName==="something"){
obj.Delete();
}
}
After some thinking, and no answer to my question, I am thinking about using some sort of dictionary (a hashmap equivalent) to track all the objects
if the variable is part of an object, you can traverse on it :
var obj {
myVar: 'hello'
};
for (var varName in obj) {
alert(varName + ' = ' + obj[varName]);
}

How to merge these arrays/json objects?

I am a bit confused at this point on what is an object, what is an array, and what is a JSON. Can someone explain the differences in syntax between the two? and how to add items to each, how to merge each type, and such? I am trying to get this function to take the new information from a JSON object (I think) and merge it with some new information. This information will then be passed to a PHP script to be processed.
Here is the console output:
{"public":{"0":["el29t7","3bmGDy"]}}
{"public":"[object Object][object Object]"}
Here is the JS I am using:
/* Helper function to clean up any current data we have stored */
function insertSerializedData(ids, type) {
// Get anything in the current field
current_data = $('#changes').val();
if (!current_data) {
var data = {};
data[index++] = ids;
var final_data = {};
final_data[type] = data;
$('#changes').val(JSON.stringify(final_data));
} else {
current_data = JSON.parse(current_data);
var data = {};
data[index++] = ids;
// Does the index exist?
if (type in current_data) {
var temp_data = current_data[type];
current_data[type] = temp_data + data;
} else {
current_data[type] = data;
}
//var extra_data = {};
//extra_data[type] = data;
//$.merge(current_data, extra_data);
$('#changes').val(JSON.stringify(current_data));
}
console.log($('#changes').val());
}
The idea is if the key (public, or whatever other ones) doesn't exist yet, then to make it point to an array of arrays. If it does exist though, then that of array of arrays need to be merged with a new array. For instance:
If I have
{"public":{"0":["el29t7","3bmGDy"]}}
and I want to merge it with
["aj19vA", "jO71Ba"]
then final result would be:
{"public":{"0":["el29t7","3bmGDy"], "1":["aj19vA", "jO71Ba"]}}
How can i go about doing this? Thanks
Excellent two-part question. Overall, the second question is non-trivial because of the complexity of the first.
Question 1:
what is an object, what is an array, and what is a JSON. Can someone
explain the differences in syntax between the two?
Question 2:
and how to add items to each,
Question 3:
how to merge each type, and such?
Answer 1:
This is a common stumbling point because, JavaScript is more flexible than one might initially expect. Here is the curve.
In JavaScript everything is an object.
So here is the code for each:
//What is an object?
var obj = { };
var obj2 = { member:"value", myFunction:function(){} }
Above is an empty object. Then another object with a variable and a function.
They are called object-literals.
//What is an array
var array1 = [ ] ;
var array2 = [0,1,2,3,4];
Above is an empty array. Then another array with five Integers.
Here is the curve that causes confusion.
//Get elements from each of the prior examples.
var x = obj2["member"];
var y = array2[1];
What??? Both Object and Array are accessing values with a bracket?
This is because both are objects. This turns out to be a nice flexibility for writing advanced code. Arrays are objects.
//What is JSON?
JSON stands for JavaScript Object Notiation. As you might have guessed. Everything is an object... It is also an { }; But it is different because - it is used to transfer data to - and - from JavaScript, not actually used (commonly) in JavaScript. It is a file transfer format.
var JSONObject = {"member":"value"};
The only difference to the prior example is quotes. Essentially we are wrapping the object literal as a string so that it can be transferred to a server, or back, and it can be reinterpreted, very easily. Better than XML - because it does not have to be custom-parsed. Just call, stringify() or ParseJSON(). Google it. The point is... JSON can be converted into an object-literal JS object, and JS object-literals can be converted into JSON, for transfer to a server or a CouchDB database, for example.
Sorry for the tangent.
Answer 2:
How to add an item to each? Here is where the curve stops being a nuisance, and starts being awesome! Because everything is an object, it is all just about the same.
//Add to an object
var obj {member1:"stringvalue"}
obj.member2 = "addme"; //That is it!
//Add to an array
var array1 [1,2,3,4,5];
array1[0] = "addme";
array[6] = null;
//We shouldn't mix strings, integers, and nulls in arrays, but this isn't a best-practice tutorial.
Remember the JS object syntax and you may start to see a whole new flexible world of objects open up. But it may take a bit.
Answer 3: Ah, yeah... how to merge.
There are seriously (very many) ways to merge two arrays. It depends on exactly what you need. Sorted, Duplicated, Concatenated... there are a few.
Here is the answer!
UPDATE: How to make a beautiful multiple dimensional array.
//Multiple Dimension Array
var array1 = [1,2,3];
var array2 = [3,4];
var arraysinArray = [array1,array2]; //That is it!
Here is the curve again, this could be in an object:
var obj{
array1:[1,2,3],
array2:[3,4]
}
JavaScript is powerful stuff, stick with it; it gets good. : )
Hope that helps,
All the best!
Nash
In this case, think of a JavaScript's object literal {} as being like PHP's associative array.
Given that, an "array of arrays" actually looks like this (using your above desired output):
{public: [["el29t7","3bmGDy"], ["aj19vA", "jO71Ba"]]}
So here we have an object literal with a single property named "public" whose value is a 2-dimensional array.
If we assign the above to a variable we can then push another array onto "public" like this:
var current_data = {public: [["el29t7","3bmGDy"], ["aj19vA", "jO71Ba"]]};
// Using direct property access
current_data.public.push(["t9t9t9", "r4r4r4"]);
// Or using bracket notation
current_data["public"].push(["w2w2w2", "e0e0e0"]);
current_data's value is now:
{public: [
["el29t7","3bmGDy"],
["aj19vA", "jO71Ba"],
["t9t9t9", "r4r4r4"],
["w2w2w2", "e0e0e0"]
]}
So now "public" is an array whose length is 4.
current_data.public[0]; // ["el29t7","3bmGDy"]
current_data.public[1]; // ["aj19vA", "jO71Ba"]
current_data.public[2]; // ["t9t9t9", "r4r4r4"]
current_data.public[3]; // ["w2w2w2", "e0e0e0"]
MDN has very good documentation on Array for insight on other functions you might need.
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array
First is an object, that contains array, second is an array.
DEMO showing display output http://jsfiddle.net/GjQCV/
var object={"public":{"0":["el29t7","3bmGDy"]}};
var arr=["aj19vA", "jO71Ba"] ;
/* use object notation to add new property and value which is the array*/
object.public[1]=arr;
It'd be much more natural if {"0": ...} were a true array rather than an object, but anyway:
function maxKey(b) {
var max;
for( var key in b )
var max = key;
return max;
}
function merge(a,b) {
for( var key in a ) {
b[key] = b[key] ? (b[key][maxKey(b)+1]=a[key], b[key]) : a[key];
}
return b;
}
Note that this assumes you would insert at the next integer index
Arrays are a particular kind of Javascript object
JSON is a way of representing Javascript objects (and as such can represent arrays and more)
Objects are much more general, and can be simple objects that can be represented as JSON, or can contain functions and prototypes.
So, this is not an array of arrays (you would access items using JSON notation like myobj["0"]):
{"0":["el29t7","3bmGDy"], "1":["aj19vA", "jO71Ba"]}
This is an array of arrays, which means you can use the push method to add an item, and access items using array notation like myobj[0]:
[ ["el29t7","3bmGDy"], ["aj19vA", "jO71Ba"] ]
It seems like the structure you want is something like this:
var myobj = { "public": [ ["key", "value"], ["key", "value"] ] }
Then if you want to add/merge new items, you'd write this:
if (myobj["public"] != null) {
myobj["public"].push(["newkey", "newval"]);
} else {
myobj["public"] = ["newkey", "newval"];
}

remove intermediary object from map object

I have a couple of these and think (know) that I'm doing something wrong (or could be simpler).
html:
<div class='item-to-select' data-global-id='55'>some</div>
var l=$(this).map(function(){
t=new Object();
t.global_id=$(this).data('global-id');
return t;
}).get();
var list=l[0]; // want to remove this
How would I remove this intermediary object? Or a better way
thx
If you mean that you don't want to have to define the l variable just so you can use it once in setting up your list variable you can do this:
var list = $(this).map(function(){
return {
global_id : $(this).data('global-id')
};
}).get()[0]; // note the [0] directly after .get()
The return from any function that returns an array (or array-like object) doesn't have to be assigned to a variable before you can use it. So:
var temp = someFuncReturnsArray();
console.log(temp[0]);
// can be replaced by
console.log(someFuncReturnsArray()[0]);
Of course if you need to do further processing on the returned array you need to put it in a variable. E.g., if you need to test its length, or if the function could possibly return null in some situations, etc. In the example above if an empty array was returned then obviously [0] will be undefined.
But if you only need the return value once you can just use it directly.
Note that I've removed the t variable from your code too. When creating an empty object it is considered good practice to say obj = {} rather than saying obj = new Object(). But you can create an object with properties in one step if the property values are already known. In the case of your function the t object you create isn't manipulated in any way other than adding a single property to it before you return it, so you can simply return an object literal directly instead of doing it in three steps.
The jQuery .get() method accepts an index.
So, you can write :
var list=$(this).map(function(){
t=new Object();
t.global_id=$(this).data('global-id');
return t;
}).get(0);

Categories