Will somebody please explain how part of this function operates?
var result = {}
$.each(this.serializeArray(), function(i, v) {
result[v.name] = v.value;
});
From the above code, I do not understand the following:
result[v.name] = v.value;
I don't understand how this is giving me the results I am getting, which is an object with name value pairs. How is this working?
// result is defined as empty object
var result = {}
// your each binding most likely is inside a $('form').submit(function(){ in here });
// so this.searializeArray() converts ( whatever "this" is in your scope ) an JavaScript array of objects you iterate over where function(i <- is the key, v <- is the object)
$.each(this.serializeArray(), function(i, v) {
// so for every object in your array you take the value and assign a new object in your initial empty result object with object.name as key and object.value as value
result[v.name] = v.value;
});
// so result may look like this after that
result == {
"fooname":"foovalue",
"barname":1337
}
Related
I am using second parameter of JSON.parse() to modify the result, but I don't quite clear about the order of the function parameter and also how it work
I have read the document about the using of the reviver function (e.g https://www.ecma-international.org/ecma-262/6.0/#sec-json.parse and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse).
From what I understand, this function would work with object, and first parameter is key or property name, second function is value or property value. What I don't understand is the return value of the function.
This is what it is done in example
var obj1 = '{"a":1, "b":42}';
let text = JSON.parse(obj1, (key, value) => {
if (typeof value === 'number'){
return value * 2
}
else{
return value
}
}
)
console.log(text) // {"a": 2, "b": 84}
This work well. But when I try to modify the code since I know all value is number already
var obj1 = '{"a":1, "b":42}';
let text = JSON.parse(obj1, (key, value) =>{
return value * 2
})
console.log(text) // NaN
It is strange to me why when I delete the return value it doesn't work. I mean, with the function none of the value return undefined when I value*2 it. I then try another test
var obj1 = '{"a":1, "b":42}';
let text = JSON.parse(obj1, (key, value) => {
if (typeof value === 'number'){
console.log('This is in if',key, value)
return value * 2
}
else{
console.log('This is in else', key, value)
return value
}
}
)
console.log(text)
Another strange thing happen when the code in else statement run even when it suppose not to run because the condition is incorrect. And when it run it even print out the obj1 object, which I didn't include in the statement.
Because it will also iterate thorough the object which is {"a":1, "b":42}.It will start from most nested level and then will go the original value itself which is {"a":1, "b":42}.
According to MDN
If a reviver is specified, the value computed by parsing is transformed before being returned. Specifically, the computed value and all its properties (beginning with the most nested properties and proceeding to the original value itself) are individually run through the reviver
By the way you can shorten your function.
var obj1 = '{"a":1, "b":42}';
let text = JSON.parse(obj1, (_, value) => value * 2 || value)
console.log(text)
I'm making a dictionary of words, so there are 1,000,000+ words.
The problem comes when I need to store the word constructor. I know this is a reserved word in javascript, but I need to add it to the dictionary.
var dictionary = {}
console.log(dictionary ['word_1'])
//undefined, this is good
console.log(dictionary ['word_2'])
//undefined, this is good
console.log(dictionary ['constructor'])
//[Function: Object]
// this cause initialization code to break
How can I fix this? I could muck with the it like key=key+"_" but that seems bad. Is there anything else I can do?
Instead of using a JS object, you could use the built-in Map type which uses strings/symbols as keys and does not conflict with any existing properties.
Replace
var dictionary = {} with var dictionary = new Map()
Override the constructor key as undefined
According to the MDN Object.prototype page, the only thing that isn't hidden by the __fieldname__ schema is the "constructor field". Thus, you could just initialize your objects via { 'constructor': undefined }.
However, you would have to make sure that in your for .. in statements would filter out all keys with undefined as their value, as it would pick up constructor as a "valid" key (even though it wouldn't before you specifically set it to undefined). I.E.
for(var key in obj) if(obj[key] !== undefined) { /* do things */ }
Check for types when getting/setting
Otherwise, you could just check the type when you 'fetch' or 'store' it. I.E.
function get(obj, key) {
if(typeof obj[key] !== 'function') // optionally, `&& typeof obj[key] !== 'object')`
return obj[key];
else
return undefined;
}
I think you should store all words and translation of them in an array. When you need to translate a word, you can use find method of Array.
For example:
var dict = [
{ word: "abc", translated: "xyz" },
...
];
Then:
var searching_word = "abc";
var translation = dict.find(function (item) {
return item.word == searching_word;
});
console.log(translation.translated);
// --> xyz
To achieve expected result , use below option of using index to get value of any key value
var dictionary = {};
var dictionary1 = {
constructor: "test"
};
//simple function to get key value using index
function getVal(obj, val) {
var keys = Object.keys(obj);
var index = keys.indexOf(val);//get index of key, in our case -contructor
return obj[keys[index]]; // return value using indec of that key
}
console.log(getVal(dictionary, "constructor"));//undefined as expected
console.log(getVal(dictionary1, "constructor"));//test
console.log(dictionary["word_1"]);
//undefined, this is good
console.log(dictionary["word_2"]);
//undefined, this is good
codepen - https://codepen.io/nagasai/pen/LOEGxM
For testing , I gave one object with key-constructor and other object without constructor.
Basically I am getting the index of key first and getting value using index
I want to create data structure like that.
Var ans =[{"b":[1,2]},{"g":[100,2]}]
I want to create a new object within list if key not exists in list ans.
Else if key exists in one object of ans list then I want to add new values into the object of ans list
For Example:
Example 1) new data c:{2000}
then
Var ans =[{"b":[1,2]},{"g":[100,2]},{c:[2000]}]
Example 2) new data g:{50}
then
Var ans =[{"b":[1,2]},{"g":[100,2,500]},{c:[2000]}]
I am a beginner in node js, understand array, object concept, but not getting exact logic!
Thanks!
You can try following:
Logic
Filter array based on key
Check if object with mentioned key exists or not.
If yes, push value to this array.
If not, create a dummy object and push this object to original array.
Correction, when you do .push({key: value}), key will be considered as string.
Alternates
If you are using ES6, .push({ [key] : value })
Create a dummy object var o = {}. Set key and value to it o[key] = value and push this object.
Optimisations
Instead of setting value like obj[key] = value, since we will be operating on arrays, try obj[key] = [].concat(value). This will enable you to pass value as number or array of values.
Instead of checking the existence of value in .filter, try Array.isArray to check if value exists and is of type array.
Custom function
function checkAndPush(array, key, value) {
var filteredList = array.filter(function(o) {
return Array.isArray(o[key]);
});
filteredList.length > 0 ? filteredList[0][key].push(value) : array.push({
[key]: [].concat(value)
});
return array;
}
var ans =[{"b":[1,2]},{"g":[100,2]}]
console.log(checkAndPush(ans, "c", [2,3]))
console.log(checkAndPush(ans, "c", 4));
Prototype function
Array.prototype.checkAndPush = function(key, value) {
var filteredList = this.filter(function(o) {
return Array.isArray(o[key]);
});
var dummy = {}
dummy[key] = [].concat(value)
filteredList.length > 0 ? filteredList[0][key].push(value) : this.push(dummy);
// or ES6: this.push({ [key]: [].concat(value) })
return this;
}
var ans =[{"b":[1,2]},{"g":[100,2]}]
console.log(ans.checkAndPush("c", [2,3]))
console.log(ans.checkAndPush("c", 4));
If you are dealing with objects as your values
ans[key] = ans[key] || []
ans[key].push(value)
Note, this works because your values will be an array. If they could be primatives then you would use hasOwnProperty to check.
if (ans.hasOwnProperty(key)) {
// Add this to your key somehow
} else {
// initialize the key with your value
}
Node.js is nothing but a library built on javascript. You can do anything using javascript type of progmming. However push and pop method should be able to help you to deal with nodejs array.
ans[key].push(value)
I have a variable holding a string of validated JSON. The JSON is a set of strings each with a value of an array. I'd like to access the string and each array value.
var json_string = {"div-1":["div-1A", "div-1B"], "div-2":["div-2A", "div-2B"]};
//Run some code to get the following result:
console.log("div-1" has "div-1A");
console.log("div-1" has "div-1B");
console.log("div-2" has "div-2A");
console.log("div-2" has "div-2B");
I have tried a bunch of different things but nothing seems to work right. Additionally, I get a weird functionality. If I do the following:
console.log(json_string["div-1"]);
I randomly get the following results for each page refresh :
div-1A //initial load
div-1C //refresh 1
div-1A //refresh 2
div-1B //etc
div-1A //etc
Any ideas how I can get what I am after?
You can first retrieve the values from keys and then use forEach to get their value
var json_string = {"div-1":["div-1A", "div-1B"],
"div-2":["div-2A", "div-2B"]
};
for(var key in json_string){
var _getValue = json_string[key]
if(_getValue.constructor===Array){ // Checking if it is an array
_getValue.forEach(function(item){
document.write('<pre>'+item+'</pre>')
})
}
JSFIDDLE
It'll be something like this if I understand correctly. You have to traverse through each property and take the array property value against that key.
for (key in json_string) {
var arr = json_string[key];
arr.forEach(function(item) {
console.log(key + ' has ' + item);
});
}
Use Object.keys() for getting all object keys and Array#forEach for iterating over array.
var json_string = {
"div-1": ["div-1A", "div-1B"],
"div-2": ["div-2A", "div-2B"]
};
// Get all object keys and iterate over them
Object.keys(json_string).forEach(function(key) {
// Get inner array using key and iterate
json_string[key].forEach(function(el) {
console.log(key + ' has ' + el)
});
});
For older browser check polyfill option for Object.keys method and forEach method.
It looks like your json_string is actually a JSON object (there's a difference). That said, keys within an object do not follow any sort/ordering. You will need to sort your keys before your output:
var obj = {
"div-1": ["div-1A", "div-1B"],
"div-2": ["div-2A", "div-2B"]
};
Object.keys( obj ).sort().forEach( key =>
obj[ key ].sort().forEach( val =>
console.log( [key,'has',val].join(' ') )
)
);
Of course you could also write your own function to output values for a specific key. Below adds a prototype function to Object, which is just an example (prototyping is generally not recommended):
Object.prototype.valuesFor = function(key){
this[key].sort().forEach( val =>
console.log( [key,'has',val].join(' ') )
)
return this[key];
};
var obj = {
"div-1": ["div-1A", "div-1B"],
"div-2": ["div-2A", "div-2B"]
};
obj.valuesFor('div-1')
I an working in javascript and stuck in understanding the objects.
Here is my scenario.
I have an object which in turn has multiple objects in it like.
data {
"aa" : object
"bb" : object
"cc" : object
}
//expanding aa bb and cc
aa {
name : "a"
type : "static"
value : "123"
}
bb {
name : "b"
type : "dyn"
value : "343"
}
cc {
name : "c"
type : "dyn"
value : "545"
}
Now what I want to achieve is that i have an object which should have those objects that have type = "dyn"
so i want to have a reqdata object like this
reqdata {
"bb" : object
"cc" : object
}
I have written a code to do this but it is not working as my reqdata has all the data.
var reqData = $.each (data, function(key, d){
if (type === "dyn")
return d;
});
Can any one guide me what the proper and efficient way of looping through the object.
Thanks any help and guidance will be appreciated
You need to create a new object, test the type property, and assign the current sub-object to the new one if the type is what you want.
// v--- Holds the results
var newObj = {};
// v--- The current sub-object
$.each(data, function(key, obj){
if (obj.type === "dyn") // <-- Test its `type` property
newObj[key] = obj; // <-- and assign to `newObj` if it matches
});
You should note that you're not making a copy of obj when you assign it to newObj. You're making a copy of a reference to obj.
This means that data and newObj share the same objects. Changes made via data are observable from newObj, and vice versa.
If you're used to functional programming, you can write your own filter function for objects:
function oFilter (obj, f) {
var result = {};
for (var x in obj) {
if (
obj.hasOwnProperty(x) &&
f(x,obj[x])
) {
result[x] = obj[x];
}
}
return result;
}
Then it'd be as you expected:
var reqData = oFilter(data, function(key,d){
if (d.type === "dyn") return true;
return false;
});
Similarly for map:
function oMap (obj, f) {
var result = {};
for (var x in obj) {
if (obj.hasOwnProperty(x)) {
result[x] = f(x,obj[x]);
}
}
return result;
}
Reduce doesn't make sense for objects though.
Shorter.
$(data).each( function(){
if(this.type === 'dyn'){ doStuff(this); }
} );
Now, IMO, constructor name is closer to type in JS. I'd build those objects with a function constructor names 'Dyn' and check <instance>.constructor.name for 'Dyn' but you would have to normalize for IE<=8 which involves parsing <instance>constructor.toString() so perhaps more trouble than it's worth.
But if you want to understand JS objects. Ditch the jQuery until you do. Learn how to use:
for(var x in object){
console.log('propertyLabel:' +x+', property:' + object[x]+'\n');
}
Then go back to understanding how jQuery itself works. Lots of juicy stuff under the hood there.