javascript keys and objects - javascript

I have a javascript code below:
function init() {
var data_pie = [];
var data_key = [];
data_pie.push(10,12,30,40,80,25);
data_key.push("x1","x2","x3","x4","x5","x6");
g.update(data_pie, data_key);
}
update: function(data, key) {
var i=-1;
var streakerDataAdded = d3.range(data.length).map(function() {
i++;
return {
name: key[i],
totalPlayers: data[i]
}
});
}
How can I optimize my code to use this object:
var data='{"data":[{"x1":"10","x2":"12","x3":"30","x4":"40","x5":"80","x6":"25"}]}';
Instead data_pie and data_key arrays?

Without being able to test this (not having any access to the rest of your code), you might try something like:
function init() {
var data='{"data":[{"x1":"10","x2":"12","x3":"30","x4":"40","x5":"80","x6":"25"}]}';
for(key in data.data[0]){
g.update(data.data[0][key], key, data.data[0].length);
}
}
update: function(data, key, length) {
var streakerDataAdded = d3.range(length).map(function() {
return {
name: key,
totalPlayers: data
}
});
}

It is very unclear as to why you would use such a data structure but anyway, here we go:
var jsonData = '{"data":[{"x1":"10","x2":"12","x3":"30","x4":"40","x5":"80","x6":"25"}]}';
// var cleanerJsonData = '{"x1":"10","x2":"12","x3":"30","x4":"40","x5":"80","x6":"25"}';
function update(json){
var data = JSON.parse(json).data[0]; // why use an array here?
// var data = JSON.parse(json) - using cleanerJsonData.
var streakerDataAdded = d3.map(data).entries().map(function(d){
return {name: d.key, totalPlayers: d.value} })
}
}

Related

Javascript OOP private functions

I would like to create a constructor which can be instantiated with a json file which then is used by some private functions which in the end pass their results to a public function of the prototype. Is this the right approach?
Here more specific code:
//constructor
function queryArray(json){
this.json = json;
//init qry template with default values
function qryInit() {
var qryTemplate = {
//some stuff
}
return qryTemplate;
}
//generate array of request templates
function qryTempArray(json){
var template = qryInit();
var qryTempArray1 = [];
for(var i = 0; i < json.length; i++){
qryTempArray1.push({
'SearchIndex': json[i].SearchIndex,
'Title': json[i].Title,
'Keywords': json[i].Keywords,
'MinimumPrice': json[i].MinimumPrice,
'MaximumPrice': json[i].MaximumPrice,
'ResponseGroup': template.ResponseGroup,
'sort': template.sort
});
}
return qryTempArray1;
}
}
//function for finally building all the queries
queryArray.prototype.qryBuilder = function(){
var qryTempArray1 = [];
qryTempArray1 = qryTempArray(this.json);
//other stuff
}
If I call the qryBuilder function on an Object, I get an error
in the function qryTempArray at the json.length in the for loop (undefined).
Why that?
As the code is written above, I'm surprised you even get to the loop. It would seem you'd get undefined when you called qryBuilder();
I would expect something along the lines of the following to work.
//constructor
function queryArray(json) {
var self = this;
self.json = json;
//init qry template with default values
self.qryInit = function() {
var qryTemplate = {
//some stuff
}
return qryTemplate;
}
//generate array of request templates
self.qryTempArray = function(json) {
var template = self.qryInit();
var qryTempArray1 = [];
for (var i = 0; i < json.length; i++) {
qryTempArray1.push({
'SearchIndex': json[i].SearchIndex,
'Title': json[i].Title,
'Keywords': json[i].Keywords,
'MinimumPrice': json[i].MinimumPrice,
'MaximumPrice': json[i].MaximumPrice,
'ResponseGroup': template.ResponseGroup,
'sort': template.sort
});
}
return qryTempArray1;
}
return self;
}
queryArray.prototype.qryBuilder = function() {
var qryTempArray1 = [];
qryTempArray1 = this.qryTempArray(this.json);
return qryTempArray1;
}
var q = new queryArray([{
'SearchIndex': 0,
'Title': 'foo',
'Keywords': 'testing',
'MinimumPrice': 20,
'MaximumPrice': 40
}]);
console.log(q);
console.log(q.qryBuilder());

Javascript object transform

I want to transform this object so that I can call it that way
cars.ox, bikes.ox
var baseValue = [
{
'2014-12-01': {
'cars;ox;2014-12-01':100,
'cars;ot;2014-12-01':150,
'bikes;ox;2014-12-01':50,
'bikes;ot;2014-12-01':80
},
'2014-12-02': {
'cars;ox;2014-12-02':100,
'cars;ot;2014-12-02':150,
'bikes;ox;2014-12-02':50,
'bikes;ot;2014-12-02':80
}
}
]
I try do this in many ways, but at the end i completely lost all hope.
var category = []
var obj = baseValue[0]
Object.keys(obj).forEach(function(key) {
var dane = obj[key]
Object.keys(dane).forEach(function(key) {
splitted = key.split(';')
var category = splitted[0]
var serviceName = splitted[1];
})
})
I would be grateful if anyone help me with this
I think you were close, you just need to create objects if they do not exist for the keys you want. Perhaps something like this.
var obj = baseValue[0]
var result = {};
Object.keys(obj).forEach(function(key) {
var dane = obj[key]
Object.keys(dane).forEach(function(key) {
splitted = key.split(';')
var category = splitted[0]
var serviceName = splitted[1];
if(!result[category]) {
result[category] = {};
}
if(!result[category][serviceName]) {
result[category][serviceName] = [];
}
result[category][serviceName].push(dane[key]);
})
});
http://jsfiddle.net/6c5c3qwy/1/
(The result is logged to the console.)

get specific text from value with javascript

I have a json.json file like this
{
"name1":"ts1=Hallo&ts2=Hillarry&ts3=Sting&ts4=Storm",
"name2":"st1=Hallo2&st2=Hillarry2&st3=Sting2&st4=Storm2",
"name3":"dr1=Hallo3&dr2=Hillarry3&dr3=Sting3&dr4=Storm3",
"name4":"ds1=Hallo4&ds2=Hillarry4&ds3=Sting4&ds4=Storm4"
}
And this script im using to read the file
<script type='text/javascript'>
$(window).load(function(){
$.getJSON("json.json", function(person){
document.write(person.name3);
});
});
</script>
This script is made to point out all of the data from "name3" but i need only "dr3" value from "name3" to be stored to be written.
How to do that?
You can store it like this using combination of split() calls.
var dr3val = person.name3.split("&")[2].split("=")[1];
console.log(dr3val); // "Sting3"
The above will work if the order is same. Else you can use the below
var dr3val = person.name3.replace(/.*?dr3=(.+)?&.*/,"$1");
console.log(dr3val); // "Sting3"
You should change your json to this:
{
"name1":
{
"ts1" : "Hallo",
"ts2" : "Hillarry",
"ts3" : "Sting",
"ts4" : "Storm"
}
}
this way it makes your jsonstring much easier to use.
Get the data from it like this:
person.name1.ts1
var json = {
"name1":"ts1=Hallo&ts2=Hillarry&ts3=Sting&ts4=Storm",
"name2":"st1=Hallo2&st2=Hillarry2&st3=Sting2&st4=Storm2",
"name3":"dr1=Hallo3&dr2=Hillarry3&dr3=Sting3&dr4=Storm3",
"name4":"ds1=Hallo4&ds2=Hillarry4&ds3=Sting4&ds4=Storm4"
};
var name3 = json.name3.split('&');
for (var i = 0; i < name3.length; i++) {
if (name3[i].indexOf("dr3=") > -1) {
var value = name3[i].replace("dr3=", "");
alert(value);
}
}
Implement this jQuery plugin i made for a similar case i had to solve some time ago. This plugin has the benefit that it handles multiple occurring variables and gathers them within an array, simulating a webserver behaviour.
<script type='text/javascript'>
(function($) {
$.StringParams = function(string) {
if (string == "") return {};
var result = {},
matches = string.split('&');
for(var i = 0, pair, key, value; i < matches.length; i++) {
pair = matches[i].split('=');
key = pair[0];
if(pair.length == 2) {
value = decodeURIComponent(pair[1].replace(/\+/g, " "));
} else {
value = null;
}
switch($.type(result[key])) {
case 'undefined':
result[key] = value;
break;
case 'array':
result[key].push(value);
break;
default:
result[key] = [result[key], value];
}
}
return result;
}
})(jQuery);
</script>
Then in your code do:
<script type='text/javascript'>
$(window).load(function(){
var attributes3;
$.getJSON("json.json", function(person){
attributes3 = $.StringParams(person.name3)
console.log(attributes3.dr3);
});
});
</script>
Underscore solution:
_.map(json, function(query) { //map the value of each property in json object
return _.object( //to an object created from array
query.split('&') //resulting from splitting the query at &
.map(function(keyval) { //and turning each of the key=value parts
return keyval.split('='); //into a 2-element array split at the equals.
);
})
The result of the query.split... part is
[ [ 'ts1', 'Hallo'], ['ts2', 'Hillarry'], ... ]
Underscore's _.object function turns that into
{ ts1: 'Hallo', ts2: 'Hillarry', ... }
The end result is
{
name1: { ts1: 'hHallo', ts2: 'Hillarry, ...},
name2: { ...
}
Now result can be obtained with object.name3.dr3.
Avoiding Underscore
However, if you hate Underscore or don't want to use it, what it's doing with _.map and _.object is not hard to replicate, and could be a useful learning exercise. Both use the useful Array#reduce function.
function object_map(object, fn) {
return Object.keys(object).reduce(function(result, key) {
result[key] = fn(object[key]);
return result;
}, {});
}
function object_from_keyvals(keyvals) {
return keyvals.reduce(function(result, v) {
result[v[0]] = v[1];
return result;
}, {});
}
:
var person={
"name1":"ts1=Hallo&ts2=Hillarry&ts3=Sting&ts4=Storm",
"name2":"st1=Hallo2&st2=Hillarry2&st3=Sting2&st4=Storm2",
"name3":"dr1=Hallo3&dr2=Hillarry3&dr3=Sting3&dr4=Storm3",
"name4":"ds1=Hallo4&ds2=Hillarry4&ds3=Sting4&ds4=Storm4"
}
var pN = person.name3;
var toSearch = 'dr3';
var ar = pN.split('&');
var result = '';
for(var i=0; i< ar.length; i++)
if(ar[i].indexOf(toSearch) >= 0 )
result=ar[i].split('=')[1];
console.log('result=='+result);

Serialize JavaScript object into JSON string

I have this JavaScript prototype:
Utils.MyClass1 = function(id, member) {
this.id = id;
this.member = member;
}
and I create a new object:
var myobject = new MyClass1("5678999", "text");
If I do:
console.log(JSON.stringify(myobject));
the result is:
{"id":"5678999", "member":"text"}
but I need for the type of the objects to be included in the JSON string, like this:
"MyClass1": { "id":"5678999", "member":"text"}
Is there a fast way to do this using a framework or something? Or do I need to implement a toJson() method in the class and do it manually?
var myobject = new MyClass1("5678999", "text");
var dto = { MyClass1: myobject };
console.log(JSON.stringify(dto));
EDIT:
JSON.stringify will stringify all 'properties' of your class. If you want to persist only some of them, you can specify them individually like this:
var dto = { MyClass1: {
property1: myobject.property1,
property2: myobject.property2
}};
It's just JSON? You can stringify() JSON:
var obj = {
cons: [[String, 'some', 'somemore']],
func: function(param, param2){
param2.some = 'bla';
}
};
var text = JSON.stringify(obj);
And parse back to JSON again with parse():
var myVar = JSON.parse(text);
If you have functions in the object, use this to serialize:
function objToString(obj, ndeep) {
switch(typeof obj){
case "string": return '"'+obj+'"';
case "function": return obj.name || obj.toString();
case "object":
var indent = Array(ndeep||1).join('\t'), isArray = Array.isArray(obj);
return ('{['[+isArray] + Object.keys(obj).map(function(key){
return '\n\t' + indent +(isArray?'': key + ': ' )+ objToString(obj[key], (ndeep||1)+1);
}).join(',') + '\n' + indent + '}]'[+isArray]).replace(/[\s\t\n]+(?=(?:[^\'"]*[\'"][^\'"]*[\'"])*[^\'"]*$)/g,'');
default: return obj.toString();
}
}
Examples:
Serialize:
var text = objToString(obj); //To Serialize Object
Result:
"{cons:[[String,"some","somemore"]],func:function(param,param2){param2.some='bla';}}"
Deserialize:
Var myObj = eval('('+text+')');//To UnSerialize
Result:
Object {cons: Array[1], func: function, spoof: function}
Well, the type of an element is not standardly serialized, so you should add it manually. For example
var myobject = new MyClass1("5678999", "text");
var toJSONobject = { objectType: myobject.constructor, objectProperties: myobject };
console.log(JSON.stringify(toJSONobject));
Good luck!
edit: changed typeof to the correct .constructor. See https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/constructor for more information on the constructor property for Objects.
This might be useful.
http://nanodeath.github.com/HydrateJS/
https://github.com/nanodeath/HydrateJS
Use hydrate.stringify to serialize the object and hydrate.parse to deserialize.
You can use a named function on the constructor.
MyClass1 = function foo(id, member) {
this.id = id;
this.member = member;
}
var myobject = new MyClass1("5678999", "text");
console.log( myobject.constructor );
//function foo(id, member) {
// this.id = id;
// this.member = member;
//}
You could use a regex to parse out 'foo' from myobject.constructor and use that to get the name.
Below is another way by which we can JSON data with JSON.stringify() function
var Utils = {};
Utils.MyClass1 = function (id, member) {
this.id = id;
this.member = member;
}
var myobject = { MyClass1: new Utils.MyClass1("5678999", "text") };
alert(JSON.stringify(myobject));
function ArrayToObject( arr ) {
var obj = {};
for (var i = 0; i < arr.length; ++i){
var name = arr[i].name;
var value = arr[i].value;
obj[name] = arr[i].value;
}
return obj;
}
var form_data = $('#my_form').serializeArray();
form_data = ArrayToObject( form_data );
form_data.action = event.target.id;
form_data.target = event.target.dataset.event;
console.log( form_data );
$.post("/api/v1/control/", form_data, function( response ){
console.log(response);
}).done(function( response ) {
$('#message_box').html('SUCCESS');
})
.fail(function( ) { $('#message_box').html('FAIL'); })
.always(function( ) { /*$('#message_box').html('SUCCESS');*/ });
I was having some issues using the above solutions with an "associative array" type object. These solutions seem to preserve the values, but they do not preserve the actual names of the objects that those values are associated with, which can cause some issues. So I put together the following functions which I am using instead:
function flattenAssocArr(object) {
if(typeof object == "object") {
var keys = [];
keys[0] = "ASSOCARR";
keys.push(...Object.keys(object));
var outArr = [];
outArr[0] = keys;
for(var i = 1; i < keys.length; i++) {
outArr[i] = flattenAssocArr(object[keys[i]])
}
return outArr;
} else {
return object;
}
}
function expandAssocArr(object) {
if(typeof object !== "object")
return object;
var keys = object[0];
var newObj = new Object();
if(keys[0] === "ASSOCARR") {
for(var i = 1; i < keys.length; i++) {
newObj[keys[i]] = expandAssocArr(object[i])
}
}
return newObj;
}
Note that these can't be used with any arbitrary object -- basically it creates a new array, stores the keys as element 0, with the data following it. So if you try to load an array that isn't created with these functions having element 0 as a key list, the results might be...interesting :)
I'm using it like this:
var objAsString = JSON.stringify(flattenAssocArr(globalDataset));
var strAsObject = expandAssocArr(JSON.parse(objAsString));

Losing object reference on lookup in Javascript

I'm working on an extension for Google Chrome and I ran into the following situation:
I'm trying to get all the existing tabs from all the opened windows in the same instance of Google Chrome. I manage to get them and construct an array of objects that contain the relevant data for me.
When I look at the constructed array using console.log (which is saved for future use also) I can see the collection of objects, but I can't reference them (when I try I get undefined).
I tried to save the array outside my object in a container, but nothing changes.
Any idea why the reference to the objects go away when I try to look them up? Thanks.
Here is the code:
(function(window){
//defining a namespace
var example = {
bmarksmaster: (function() {
var bmarksmaster = function() {
return new bmarksmaster.fn.init();
}
bmarksmaster.fn = bmarksmaster.prototype = {
debug: false,
tabs: [],
constructor: bmarksmaster,
init: function() {
return this;
},
windowParser: function(ctx, filter) {
var local = ctx;
var filter = filter;
return function(wObj) {
if((wObj !== null) && (wObj !== undefined)) {
for(var idx in wObj) {
var cw = wObj[idx];
if((cw.tabs !== null) && (cw.tabs !== undefined)) {
var cwtabs = cw.tabs;
for(var tabIdx in cwtabs) {
local.tabs.push(filter(tabIdx, cwtabs[tabIdx]));
}
}
}
}
};
},
getTabs: function() {
var returnData = [];
chrome.windows.getAll(
{
"populate": true
}, this.windowParser(this, function(i, e) {
var data = {};
if(!e.incognito) {
data["title"] = e.title;
data['url'] = e.url;
data['favicon'] = e.favIconUrl || "";
}
return data;
}));
return this.tabs;
},
getTab: function(callback) {
this.getTabs();
for (var tabIdx in this.tabs) {
if(callback(tabIdx, this.tabs[tabIdx])) {
return this.tabs[tabIdx];
}
}
},
getTabsData: function(callback) {
var data = [];
var tabs = [];
tabs = this.getTabs();
console.log(this.tabs[0]);
for (var tabIdx in tabs) {
console.log(tabs[tabIdx]);
var tabData = callback(tabIdx, tabs[tabIdx]);
if(tabData) {
data.push(tabData);
}
}
return data;
},
setDebug: function() {
this.debug = true;
},
resetDebug: function() {
this.debug = false;
}
};
bmarksmaster.fn.init.prototype = bmarksmaster.fn;
return bmarksmaster;
})()
};
window.example = example;
})(window);
//end of bmarksmaster.js file
console.log(example.bmarksmaster().getTabs()); //this works, I can see the array
console.log(example.bmarksmaster().getTabs()[0]); //this doesn't work, I get undefined, never mind the shortcut
I think the logic in your code is wrong. It is a bit convoluted and hard to follow. I would recommend rewriting it a bit to be simpler. Something like this might help get you started. It collects all the windows, putts all the tabs into the tabs var.
var tabs = [];
chrome.windows.getAll({ populate: true}, function(windows) {
var localTabs = windows.reduce(function(a, b){
return a.tabs.concat(b.tabs);
});
tabs = localTabs.filter(function(element){
return !element.incognito;
});
})

Categories

Resources