strange data in array.toSource() learning genetic algorithm - javascript

I'm just starting to learn genetic algorithms and I'm essentially writting this tutorial http://lethain.com/entry/2009/jan/02/genetic-algorithms-cool-name-damn-simple/ to javascript. with a few changes which better represent my dataset.
Anyway, when I output via newPop.toSource(), I get
[[#1=[[30,22],#2=[30,85],#3=[30,76]...]]],[#1#,#2#,#3#...#15]]]
I've never seen my .toSource output look like this, I was expecting just an array with two arrays inside it
My code is
var newPop=populate(data,population,0,70);
function individual(population, min, max){
var newIndivids=[];
for(s in population){
newIndivids.push(population[s]);
newIndivids[s][0]+=rand;
}
return newIndivids;
}
function populate(count,population,min,max){
var popul=[];
for(indiv in count){
popul.push(individual(population,min,max));
}
return popul;
}
Is there something I'm doing wrong in my code which is giving me this strange array structure??

Not sure what those #1, #2, ... things are, but toSource() is gecko specific: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/toSource
My guess is that it's some kind of "reference" to the object in memory at that point, i.e. not portable output.
I suggest you use JSON.stringify instead, which will output a portable string representation of your data structure.
The JSON global object will be available in Firefox/Safari/Chrome out of the box, but if you also need it in IE you can get it here: http://www.json.org/js.html
Then to reverse this and get back an actual living object, use JSON.parse:
var data = JSON.parse(str);

Related

Convert JSON with objects and arrays to String

I have a JSON object which looks like this:
{
files: ['test.mp4'],
name: ['testFile'],
hints: ['%YES%_%MAYBE%_%NO%']
}
And I need to convert it to a String so the output looks like this:
[{files=test, name=testFile, hints= %YES%_%MAYBE%_%NO%}]
Is this possible to achieve in Node JS? Thanks
I tried the following:
var x = {
files: ['test.mp4'],
name: ['testFile'],
hints: ['%YES%_%MAYBE%_%NO%']
}
console.log(JSON.stringify(x));
But the output looks like this:
{"files":["test.mp4"],"name":["testFile"],"hints":["%YES%_%MAYBE%_%NO%"]}
Still with the square brackets. I may not 100% know the keys and values in the object above.
Try
JSON.stringify(obj)
then you get a string with quotes etc.
JavaScript has JSON.stringify() method which can convert an object into string:
var x = {
files: ['test.mp4'],
name: ['testFile'],
hints: ['%YES%_%MAYBE%_%NO%']
}
console.log(JSON.stringify(x));
// result: '{"files":["test.mp4"],"name":["testFile"],"hints":["%YES%_%MAYBE%_%NO%"]}'
This will result in a string which can be transformed back to JS object with JSON.parse() method. If you still want to remove all brackets and quotes, you can simply use JavaScript's replace() method (replacing characters [, ], and " with empty string), but this will replace those characters in all your values (if any) and will result in (sort of) non-reusable string.
TL;DR Don't do this unless you absolutely have to (ie. you're dealing with a messed up API written by someone else that must have the data in this format)
If you want exactly the format listed in your question, then you're going to have to write your own stringify function that recursively walks through the object you pass to it and applies whatever rules you want to use. You will have to consider all the possible permutations of your object and spell out those rules.
For example, you've converted arrays with single elements in the initial object into strings - what happens if there is more than one element in the array? Should it be delimited by a comma or some other character? Should we just throw away elements after the first?
And once you've written the stringify function, you'll also have to write the corresponding parse function to reverse it. And it should be mentioned that in your example, you're throwing away information (eg. the file extension on the .mp4 file) - how are you going to handle that?
A much, much better way to approach this would be to do what other people have suggested here: use JSON.stringify and rewrite your code to use standard JSON objects. Why? Because the format is well documented and well understood and because the functions to convert are well tested. You will save yourself a whole lot of time and pain if you don't try to reinvent the wheel here.

JSON.parse & JSON.stringify handling long integers as strings

I have the problem, that I need to parse long integers in my API. Since I don't do anything arithmetically, it is the easiest to handle them as Strings. I tried Bignumber.js, but it starts complaining if numbers are longer than 15 characters. Unfortunately I have to handle them as well.
Since I don't do anything arithmetically with it and actually even store those numbers as String I would like a JSON Parser that parses too big numbers as Strings and is capable of also treat them as numbers in JSON.stringify.
I tried the stringify with a replacer function, but I could not get rid of the quotes around my number.
I also did not find a library, that just takes care of this issue.
Edit / Clarification
I want my big number to be a String in javascript, but a number in JSON (after JSON.stringify)
e.g. Object in Javascript
var myObj = {
id: "89074987798719283473" // <-- String within javascript
}
var objString = JSON.stringify(myObj)
Now my objString should be
{id: 89074987798719283473}
And NOT
{id: "89074987798719283473"}
If you absolutely must do this and really can't find a better place to handle this, then remember that JSON is just a string, and all the tools for string manipulation can be brought to bear on this problem. So you could do something like:
var myObj = {
id: "89074987798719283473" // <-- String within javascript
}
var json = JSON.stringify(myObj); // this is {"id":"89074987798719283473"}
var numberJson = json.replace(/"id":"(\d+)"/,'"id":$1'); // this is now {"id":89074987798719283473}
console.log(numberJson);
Of course this is hacky and error prone as you have to be very careful about what you are matching (you might have other properties called id nested in your json that you don't want manipulated). If you wanted to make it a little more robust, you could append something the end of your id before you stringify to make it easier to find and replace it in the string.

Variable in JSON

I don't have much experience with JSON, I want to know if something like this is possible.
{
"variable": "A really long value that will take up a lot of space if repeated",
"array": [variable, variable, variable]
}
Obviously that isn't valid, but I want to know if there is a way to do this. I tried using "variable" but of course that just sets the array item to the string "variable". The reason I want to do this is I need to repeat long values in a multidimensional array, which takes up a lot of space.
Thanks.
If you are willing to do some post-processing on the JSON after parsing it, then you can use a token value in your array, and replace the token after parsing with the variable. Example:
{
"variable": "A really long value",
"array": ["variable", "variable", "variable"]
}
Then, in your code that parses:
var obj = JSON.parse(str);
for (var i=0; i<obj.array.length; i++)
{
obj.array[i] = obj[obj.array[i]];
}
Are you worried about space in the output, or in the object created from the JSON? In the latter case, it's likely that the string values will be coalesced when the parsing happens.
If you're concerned about the size of the JSON, then you'll probably either want to change to another format, or de-duplicate the strings in the JSON.
You could add an object to your JSON data that maps ID numbers to strings, then use the IDs to represent te strings.
There is no way to do this in pure JSON (full spec here).
If you wanted to do something like that you might want to look into templating tools such as Handlebars
you will get your answer here jason tutorial for beginners
example:
var data={
"firstName":"Ray",
"lastName":"Villalobos",
"joined":2012
};

Convert JSON to array of objects with custom keys and values

I receive from the server a JSON string:
{0:["aNumber","aText","anID"],1:["aNumber","aText","anID"]...
I must elaborate this string so that:
aNumber is concatenated with client side strings (say, it becomes "http://www.myurl.com/aNumber.jpg");
aNumber becomes the value of url in array of objects;
aText becomes the value of caption in the same array;
anID becomes the value of id in the same array;
[{url:"http://www.myurl.com/aNumber.jpg",caption:"aText",id:"anID}.{url:"http://www.myurl.com/aNumber.jpg",caption:"aText",id:"anID"}...
I perfectly know how to do this, but I wanted to know if anyone knows if is possible to do the same thing avoiding a loop: the JSON is really huge (more than 10000 items) in a mobile context, so I was hoping in something magic to improve performances.
Try looping through 10,000 items in a mobile context. Then try 100,000 and then 1,000,000. You'll probably see that looping is not the greatest performance bottleneck.
You can't really do that, here the best solution is to convert one specific child array in the object only when you need it.
Anyway, the loop is not so long to execute, the longest is the parsing JSON String > Object.
For your loop, I would have made something like:
obj=JSON.parse({0:["aNumber","aText","anID"],1:["aNumber","aText","anID"]});
arr=[];
for(i in obj){
o=obj[i]; // improve performances on big objects
arr.push({url: "http://www.myurl.com/"+ o[0] + ".jpg", caption:o[1], id:o[2]});
}

javascript: array of object for simple localization

I need to implement a simple way to handle localization about weekdays' names, and I came up with the following structure:
var weekdaysLegend=new Array(
{'it-it':'Lunedì', 'en-us':'Monday'},
{'it-it':'Martedì', 'en-us':'Tuesday'},
{'it-it':'Mercoledì', 'en-us':'Wednesday'},
{'it-it':'Giovedì', 'en-us':'Thursday'},
{'it-it':'Venerdì', 'en-us':'Friday'},
{'it-it':'Sabato', 'en-us':'Saturday'},
{'it-it':'Domenica', 'en-us':'Sunday'}
);
I know I could implement something like an associative array (given the fact that I know that javascript does not provide associative arrays but objects with similar structure), but i need to iterate through the array using numeric indexes instead of labels.
So, I would like to handle this in a for cycle with particular values (like j-1 or indexes like that).
Is my structure correct? Provided a variable "lang" as one of the value between "it-it" or "en-us", I tried to print weekdaysLegend[j-1][lang] (or weekdaysLegend[j-1].lang, I think I tried everything!) but the results is [object Object]. Obviously I'm missing something..
Any idea?
The structure looks fine. You should be able to access values by:
weekdaysLegend[0]["en-us"]; // returns Monday
Of course this will also work for values in variables such as:
weekdaysLegend[i][lang];
for (var i = 0; i < weekdaysLegend.length; i++) {
alert(weekdaysLegend[i]["en-us"]);
}
This will alert the days of the week.
Sounds like you're doing everything correctly and the structure works for me as well.
Just a small note (I see the answer is already marked) as I am currently designing on a large application where I want to put locals into a javascript array.
Assumption: 1000 words x4 languages generates 'xx-xx' + the word itself...
Thats 1000 rows pr. language + the same 7 chars used for language alone = wasted bandwitdh...
the client/browser will have to PARSE THEM ALL before it can do any lookup in the arrays at all.
here is my approach:
Why not generate the javascript for one language at a time, if the user selects another language, just respond(send) the right javascript to the browser to include?
Either store a separate javascript with large array for each language OR use the language as parametre to the server-side script aka:
If the language file changes a lot or you need to minimize it per user/module, then its quite archivable with this approach as you can just add an extra parametre for "which part/module" to generate or a timestamp so the cache of the javascript file will work until changes occures.
if the dynamic approach is too performance heavy for the webserver, then publish/generate the files everytime there is a change/added a new locale - all you'll need is the "language linker" check in the top of the page, to check which language file to server the browser.
Conclusion
This approach will remove the overhead of a LOT of repeating "language" ID's if the locales list grows large.
You have to access an index from the array, and then a value by specifying a key from the object.
This works just fine for me: http://jsfiddle.net/98Sda/.
var day = 2;
var lang = 'en-us';
var weekdaysLegend = [
{'it-it':'Lunedì', 'en-us':'Monday'},
{'it-it':'Martedì', 'en-us':'Tuesday'},
{'it-it':'Mercoledì', 'en-us':'Wednesday'},
{'it-it':'Giovedì', 'en-us':'Thursday'},
{'it-it':'Venerdì', 'en-us':'Friday'},
{'it-it':'Sabato', 'en-us':'Saturday'},
{'it-it':'Domenica', 'en-us':'Sunday'}
];
alert(weekdaysLegend[day][lang]);

Categories