var changeJsonKeyName, newObj, obj;
changeJsonKeyName = function(json, oldName, newName) {
json[newName] = json[oldName];
delete json[oldName];
// json.newName = json.oldName;
// delete json.oldName;
// if i use point in this ,i can not get my result that i want
return json;
};
obj = {
'aaa': '1111',
'bb': {
'cc': 333
}
};
newObj = {};
newObj = changeJsonKeyName(obj, 'aaa', 'nnn');
console.log(newObj);
If I use point here ,I can not get my result that's what I want ,what is the wrong,please help me,thank you very much.
I'm not sure if I understood you correctly, but :
json[newName]
access property named with the value of newName variable
json.newName
access a property named 'newName', which does not exist
First, as a comment points out, this is a Javascript question, not a JSON question.
But you seem to be asking why this works:
json[newName] = json[oldName];
delete json[oldName];
but this doesn't:
json.newName. = json.oldName.;
delete json.oldName;
does not.
And the answer is the second form is actually equivalent to
json["newName"] = json["oldName"];
delete json["oldName"];
In other words, you are dealing with attributes whose names are the constants "oldName" and "newName" rather than attributes whose names are passed as parameters to that method.
Related
i was asked to write out a piece of code that inverts all key value pairs from an object passed in. this is what i wrote out.
invert(object){
let newObj = {};
for(let key in object){
const original = object[key];
newObj = {original : key}
}
return newObj;
}
aparently that dosent work ( and i cant figure out why). the answer to the question was
invert(object){
let invertedObject = {};
for(let key in object){
const originalValue = object[key];
invertedObject = {originalValue : key}
}
return invertedObject;
}
when ran with with a test file, my code fails while the answer code passes. reasoning was mine is returning undefined.
error code from test :
Failed: _.invert({originalKey: "originalValue"})["originalValue"])
returned undefined instead of originalKey
Difference is in the following statement:
newObj = {original : key}
In your code, when you use original as a key in the newObj, instead of using the value of the original variable as a key, 'original' is used literally as a key.
The original variable is unused in your code.
You can fix the problem by using computed property name as:
newObj = { [original]: key };
Without using the computed property, newObj will be:
{
original:"originalKey"
}
but with computed property name, newObj will be:
{
originalValue:"originalKey"
}
The second code example works because in the following statement
invertedObject = {originalValue : key}
they have used the value of the originalKey as the name of the key. So the key of the returned object will be 'originalValue'.
Also note that the following statement in the second code example
const originalValue = object[key];
is unnecessary because originalValue variable is not being used. Second code example will also work without the above statement.
If second code example uses computed property name as:
invertedObject = { [originalValue] : key }
then you need the statement that declares the originalValue variable.
Personally, I think second code example is error prone and is really easy to break; its also not practical for making a reusable function because:
objects passed to this function won't always have a single key
you won't always know the value of each key in the object and even if you do know the values, if the object has multiple keys, this approach won't work
You should use computed property name which doesn't depends on a variable name being the same as the value of a key in the object.
that inverts all key value pairs from an object passed in
You have to add each property to the same object and not create new object for each property.
function invert(object) {
let newObj = {};
for(let key in object){
const original = object[key];
newObj[original] = key; // add property to same 'newObj' object
}
return newObj;
}
console.log(invert({originalKey: "originalValue", anotherKey: "anotherValue"}))
I'm sure there is a simple way to do this, but am stumped for now.
I have many variables defined at the top of my script (here is an example of two):
var firstVar,secondVar;
Then I have an object which contains those variables:
var myObj = { a: {name:firstVar, number:1}, b: {name:secondVar, number:2}
I want to assign values to those variables:
keys = Object.keys(myObj);
function getAll(e){
var myArray = [];
for (var prop in myObj){
myArray.push(myObj.prop[e]);
}
return myArray;
}
The behaviour I want is:
var nameVars = getAll(name);
// [firstVar,secondVar]
But instead it returns:
// [undefined,undefined]
How else can I get the variables before defining them?
Then I have an object which contains those variables:
No, it doesn't. It contains a copy of the value those variables contained as of when you created the object (which is undefined, since you've never assigned a value to them). Once created, there is no ongoing link between the object property you've copied the value to and the variable.
Since the object has no enduring link to the variables, there's no way for getAll to return the information you've said you want.
You've said in a comment that you're building d3 graphs and have the same structure with some variables, and want to avoid repeating yourself. It sounds to me like you want a builder function:
function buildObject(firstVar, secondVar) {
return { a: {name:firstVar, number:1}, b: {name:secondVar, number:2} };
}
...which you would then use like this:
var obj1 = buildObject("value1", "value2");
// do a graph
var obj2 = buildObject("valueA", "valueB");
// do a graph
...or possibly even something that just takes the variables and produces the graph:
function makeGraph(firstVar, secondVar) {
buildTheGraph({ a: {name:firstVar, number:1}, b: {name:secondVar, number:2} });
}
I don't think it is, but if it's the names you want, just put them in quotes (and also myArray.push(myObj.prop[e]); should be myArray.push(myObj[prop][e]); and getAll(name) should be getAll("name")), but again there's no link to the variables at all:
// Since they're not used, we don't even need these: var firstVar, secondVar;
var myObj = { a: { name: "firstVar", number: 1 }, b: { name: "secondVar", number: 2 } };
function getAll(e) {
var myArray = [];
for (var prop in myObj) {
myArray.push(myObj[prop][e]);
}
return myArray;
}
var nameVars = getAll("name");
console.log(nameVars);
...but note that having the names doesn't help you get the variable values later (unless you use eval, which you should seek to avoid).
Lets say I have the following object:
name = {
name_one : {
name_one_A : {
name_one_A_a : 'John',
name_one_A_b : 'Kate'
}
}
};
I could create a reference to 'John' by doing:
current_name = name.name_one.name_one_A.name_one_A_a;
Lets say I'm referencing "name.name_one.name_one_A" several times, is there a way to create a referencing to this nesting? This doesn't work, but something like:
A = name.name_one.name_one_A;
name = A.name_one_A_b;
'name' would then equal 'Kate'. I know this doesn't work like that, but I'm just wondering if there is a way to accomplish this?
Thanks for any help!
It's a bit hard to tell exactly what you're asking which has caused some confusion among the answers.
If you're referencing name.name_one.name_one_A multiple times, you can save that once and then use it:
var x = name.name_one.name_one_A;
x.name_one_A_a = 'Bill';
x.name_one_A_b = 'Sue';
This works ONLY because the value of name.name_one.name_one_A is an object (Object, Array or Function). So, when you save it to another variable, you aren't actually saving a reference to name.name_one.name_one_A, but rather getting the value of that property which is itself an object. And, when you then modify that object, since name.name_one.name_one_A also points to that same object, you will see the value change there too.
Javascript does not have the ability to create a reference to a particular property on an object such that you could use only that reference to then change the value of that property.
Using C/C++ terminology, you can't create a pointer to a property on an object in Javascript such that you could change the value in that property using only that pointer.
You would instead have to pass the host object and the property name and you could then change the value of the property on that host object.
Or, if the value of the property was itself an object (Object, Array or Function), then you can get the value of the property and then change the object that it points to.
So, in your data structure:
var name = {
name_one : {
name_one_A : {
name_one_A_a : 'John',
name_one_A_b : 'Kate'
}
}
};
There's no way to get a direct reference to:
name.name_one.name_one_A.name_one_A_a
that would let you modify just the contents of that property at some later time. Instead, you'd have do something like this where you get a reference to the containing object and use that:
var obj = name.name_one.name_one_A;
var prop = "name_one_A_a";
// and then some time later:
obj[prop] = 'Bob';
// or
obj.name_one_A_a = 'Bob';
Firefox Scratchpad had an issue with a variable named "name", but this works:
var foo = {
'name_one' : {
'name_one_A' : {
'name_one_A_a' : 'John',
'name_one_A_b' : 'Kate'
}
}
};
var A = foo.name_one.name_one_A;
console.log(A.name_one_A_b);
//yields
Kate
Update:
You can get a reference that is able to change a property value:
var foo = {
'name_one' : {
'name_one_A' : {
'name_one_A_a' : 'John',
'name_one_A_b' : 'Kate'
}
}
};
var A = foo.name_one.name_one_A;
console.log(A.name_one_A_b);
A.name_one_A_b = "bob";
console.log(A.name_one_A_b);
console.log(JSON.stringify(foo));
Yields:
"Kate"
"bob"
"{"name_one":{"name_one_A":{"name_one_A_a":"John","name_one_A_b":"bob"}}}"
It's difficult to explain the case by words, let me give an example:
var myObj = {
'name': 'Umut',
'age' : 34
};
var prop = 'name';
var value = 'Onur';
myObj[name] = value; // This does not work
eval('myObj.' + name) = value; //Bad coding ;)
How can I set a variable property with variable value in a JavaScript object?
myObj[prop] = value;
That should work. You mixed up the name of the variable and its value. But indexing an object with strings to get at its properties works fine in JavaScript.
myObj.name=value
or
myObj['name']=value (Quotes are required)
Both of these are interchangeable.
Edit: I'm guessing you meant myObj[prop] = value, instead of myObj[name] = value. Second syntax works fine: http://jsfiddle.net/waitinforatrain/dNjvb/1/
You can get the property the same way as you set it.
foo = {
bar: "value"
}
You set the value
foo["bar"] = "baz";
To get the value
foo["bar"]
will return "baz".
You could also create something that would be similar to a value object (vo);
SomeModelClassNameVO.js;
function SomeModelClassNameVO(name,id) {
this.name = name;
this.id = id;
}
Than you can just do;
var someModelClassNameVO = new someModelClassNameVO('name',1);
console.log(someModelClassNameVO.name);
simple as this
myObj.name = value;
When you create an object myObj as you have, think of it more like a dictionary. In this case, it has two keys, name, and age.
You can access these dictionaries in two ways:
Like an array (e.g. myObj[name]); or
Like a property (e.g. myObj.name); do note that some properties are reserved, so the first method is preferred.
You should be able to access it as a property without any problems. However, to access it as an array, you'll need to treat the key like a string.
myObj["name"]
Otherwise, javascript will assume that name is a variable, and since you haven't created a variable called name, it won't be able to access the key you're expecting.
You could do the following:
var currentObj = {
name: 'Umut',
age : 34
};
var newValues = {
name: 'Onur',
}
Option 1:
currentObj = Object.assign(currentObj, newValues);
Option 2:
currentObj = {...currentObj, ...newValues};
Option 3:
Object.keys(newValues).forEach(key => {
currentObj[key] = newValues[key];
});
I'm trying to create an array that maps strings to variables. It seems that the array stores the current value of the variable instead of storing a reference to the variable.
var name = "foo";
var array = [];
array["reference"] = name;
name = "bar";
// Still returns "foo" when I'd like it to return "bar."
array["reference"];
Is there a way to make the array refer to the variable?
Put an object into the array instead:
var name = {};
name.title = "foo";
var array = [];
array["reference"] = name;
name.title = "bar";
// now returns "bar"
array["reference"].title;
You can't.
JavaScript always pass by value. And everything is an object; var stores the pointer, hence it's pass by pointer's value.
If your name = "bar" is supposed to be inside a function, you'll need to pass in the whole array instead. The function will then need to change it using array["reference"] = "bar".
Btw, [] is an array literal. {} is an object literal.
That array["reference"] works because an Array is also an object, but array is meant to be accessed by 0-based index. You probably want to use {} instead.
And foo["bar"] is equivalent to foo.bar. The longer syntax is more useful if the key can be dynamic, e.g., foo[bar], not at all the same with foo.bar (or if you want to use a minimizer like Google's Closure Compiler).
Try pushing an object to the array instead and altering values within it.
var ar = [];
var obj = {value: 10};
ar[ar.length] = obj;
obj.value = 12;
alert(ar[0].value);
My solution to saving a reference is to pass a function instead:
If the variable you want to reference is called myTarget, then use:
myRef = function (newVal) {
if (newVal != undefined) myTarget = newVal;
return myTarget;
}
To read the value, use myRef();. To set the value, use myRef(<the value you want to set>);.
Helpfully, you can also assign this to an array element as well:
var myArray = [myRef];
Then use myArray[0]() to read and myArray[0](<new value>) to write.
Disclaimer: I've only tested this with a numerical target as that is my use case.
My solution to saving a reference is to pass a function instead:
If the variable you want to reference is called 'myTarget', then use:
myRef = function (newVal) {
if (newVal != undefined)
myTarget = newVal;
return myTarget;
}
To read the value, use myRef();. To set the value, use myRef(value_to_set);.
Helpfully, you can also assign this to an array element as well:
var myArray = [myRef];
Then use myArray0 to read and myArray[0](value_to_set) to write.
Disclaimer: I've only tested this with a numerical target as that is my use case.