I have an array that is initialized like such var generationObject = [{string:"", score: 0}];
which I then fill dynamically:
for(var i = 0; i < amount_offspring; i++)
{
// "load" text into array and send the string to see if it evolves
generationObject[i].string = evolve(start_text, characters, mutation_rate);
// then score the string
generationObject[i].score = score(target_text, generationObject.string);
}
I then want to sort this array by score. I don't know what's best, to sort it in the for loop or sort the entire array afterwards.
I will then take the string of the highest scoring object and pass it through the function again, recursively.
So what would be a good way to go about this sort function? I've seen some here use this
generationObject.sort(function(a, b) {
return (a.score) - (b.score);
});
But I'm not sure if .sort is still supported? This didnt seem to work for me though.
generationObject is an array, not an object, so score(target_text, generationObject.string); could be the problem, as .string will be undefined. (Did you mean generationObject[i].string?)
Try building your array like this:
var generationObject = []
for(var i = 0; i < amount_offspring; i++)
{
evolved_string = evolve(start_text, characters, mutation_rate)
generationObject.push({
string: evolved_string,
score: score(target_text, evolved_string)
})
}
And then Array.prototype.sort should do the trick.
You should write your sorting logic outside the for loop, since if you put it inside, the object array will be sorted N times, where N being the iterations of your loop. The following are two ways to do it-
By using sort() function- To clarify your question, sort() is still supported across almost all the browsers. If you are still concerned about the browser compatibility, you can check the MDN documentation to see the list of supported browsers.
generationObject = generationObject.sort(function(a, b) {
return parseInt(a.score) - parseInt(b.score);
});
By using underscorejs-
In underscore, you can take advantage of the sortBy() function.
Returns a (stably) sorted copy of list, ranked in ascending order by the results of running each value through iteratee. iteratee may also be the string name of the property to sort by (eg. length).
You can simply do this in underscorejs-
generationObject = _.sortBy(generationObj, 'score');
Related
In javascript, I am little bit confused that how to get the actual and accurate probability of shuffling an object in an array.
For example
var numberOfOrder=[
{
id:1
},
{
id:2
},
{
id:3
}
]
From above example The above object can be manipulated in 6 ways By finding the factorial numberOfOrder.length;
But what is the actual way to shuffle that object in an array.
My Try
function newShuffle(value) {
for(var i = value.length-1;i >=0; i--){
var randomIndex = Math.floor(Math.random()*(i+1));
var itemAtIndex = value[randomIndex];
value[randomIndex] = value[i];
value[i] = itemAtIndex
}
return value
}
But the above function won't return accurate value if I run that function 6 times it returning Duplicate Values
What is the correct function to do it
You have to understand the difference between probability and permutations. The second term comes from combinatorics. There are some algorithms that allow to get all possible permutations of array items. Here is one of them:
function permutations(items) {
// single item array - no permutations available
if (items.length == 1) return [items];
var combos = [];
for (var i = 0; i < items.length; i++) {
// first - the current item, rest - array without the current item
var first = items[i], rest = items.slice(0);
rest.splice(i, 1);
// getting permutations of shorter array and for each of them...
permutations(rest).forEach(function(combo){
// prepend the current item
combo.unshift(first);
// save the permutation
combos.push(combo);
});
}
return combos;
}
alert(permutations([ 1, 2, 3 ]).join("\n"));
Update
The recursive algorithm is implemented above. The function permutations gets an array and for each item recursively gets all permutations beginning with current item. At each step of recursion the array is shorter by one item (minus the current item) and at the last step single element array is not being processed because permutations are not available anymore.
Also some comments added to the code.
The last line is just the test to get all permutations of array [1, 2, 3] and to show them via alert. To get more illustrative view all found permutations are glued with new line symbol (.join("\n")).
As stated by the comments and the above answer you need permutations operation. However there are many ways to obtain the permutations of an array. For further information on permutations i would advise you to have a look at Permutations in JavaScript topic.
On the other hand a recursive approach is always much slower compared to a dynamical programming approach. Recently i have come up with a permutations algorithm which seems to be the fastest of all. Check it up
I've got an array. I push items multiple times into this array using a function. Below is an simplified version of the code.
var arr = [];
function pushItems(i){
//do something with i
var abc = "string"
arr.push(abc);
//do something with i
var xyz = "string"
arr.push(xyz);
}
Sometimes abc value is pushed before xyz. Sometimes xyz gets pushed before abc value. My question is how do I always have the abc value ahead of 'xyz' value?
So basically I need the array values to be [abc1, xyz1, abc2, xyz2, abc3, xyz3, ...] so on. How do I order the push accordingly?
This is wrong. According to the specification of this method:
The push() method adds one or more elements to the end of an array and
returns the new length of the array.
Please have a look here.
For a more formal approach please see the ECMAScript specification here.
The arguments are appended to the end of the array, in the order in
which they appear. The new length of the array is returned as the
result of the call.
Update
But even if the elements are added at the end of the array, I'm
looking a way of ordering my array.
You can use the sort function for this reason passing to it an appropriate function that will do the compare. For instance, let we have the following array
var array = [4,1,2,5,3];
and we want to order it in a descending order, we could do this like below:
var array = array.sort(function(a,b){ return b-a; });
Since you need your base64-strings to be in an arbitrary order in the array, sort them by an identifier you define.
var firstObj = {id: 0, base64: 'asdf'}
var secondObj = {id: 1, base64: 'qwer'}
var arr = []
// do stuff
// callback needs to have something along these lines:
function base64isLoaded(obj){
arr[obj.id] = obj.base64;
}
Now the 'front' image (as you gave this as example) can be given id: 0, so it ends up in the '0' spot of the array. I can't really help more without more information about how your code is structured.
EDIT: From your comment ("passing multiple items into pushItems"), I am going to assume that i (the argument) is an array and you iterate this array to transform each element into a base64 encoded string. You then want these encoded strings added to arr in the same order, correct?
easily done, simply make i an array of objects:
var i = [{source: 'abc'}, {source: 'xyz'}];
pushItems(i){
for(var c = 0; c < i.length; c++){
makeIntoBase64(i[c]);
}
}
makeIntoBase64(obj){
// this is whatever function that transforms it and takes a callback when it is done
transform(obj.source, function(result){ //pass the source to be encoded
//result should be base64 encoded string
obj.encoded = result;
});
}
after all this, the array i has objects with both .source and .encoded. If you need to know when ALL encoding is done, create a counter and add one to it in the transform callback, and check if counter === i.length every time. When it is, you know you have loaded all base64 strings and can run another function, adding these images to your catalogue or whatever else you need this for :)
my array:
tempListArray = "[{"id":"12","value":false},{"id":"10","value":false},{"id":"9","value":false},{"id":"8","value":false}]";
To check if an element exists I would do this:
for (var i in tempListArray) {
//check flag
if (tempListArray[i].id == Id) {
flagExistsLoop = 1;
break;
}
}
Is there anyway, I can check if an Id exists without looping through the whole array. Basically I am worried about performance if say I have a 100 elements.
Thanks
No, without using custom dictionary objects (which you seriously don't want to for this) there's no faster way than doing a 'full scan' of all contained objects.
As a general rule of thumb, don't worry about performance in any language or any situation until the total number of iterations hits 5 digits, most often 6 or 7. Scanning a table of 100 elements should be a few milliseconds at worst. Worrying about performance impact before you have noticed performance impact is one of the worst kinds of premature optimization.
No, you can't know that without iterating the array.
However, note for...in loops are a bad way of iterating arrays:
There is no warranty that it will iterate the array with order
It will also iterate (enumerable) non-numeric own properties
It will also iterate (enumerable) properties that come from the prototype, i.e., defined in Array.prototype and Object.protoype.
I would use one of these:
for loop with a numeric index:
for (var i=0; i<tempListArray.length; ++i) {
if (tempListArray[i].id == Id) {
flagExistsLoop = 1;
break;
}
}
Array.prototype.some (EcmaScript 5):
var flagExistsLoop = tempListArray.some(function(item) {
return item.id == Id;
});
Note it may be slower than the other ones because it calls a function at each step.
for...of loop (EcmaScript 6):
for (var item of tempListArray) {
if (item.id == Id) {
flagExistsLoop = 1;
break;
}
}
Depending on your scenario, you may be able to use Array.indexOf() which will return -1 if the item is not present.
Granted it is probably iterating behind the scenes, but the code is much cleaner. Also note how object comparisons are done in javascript, where two objects are not equal even though their values may be equal. See below:
var tempListArray = [{"id":"12","value":false},{"id":"10","value":false},{"id":"9","value":false},{"id":"8","value":false}];
var check1 = tempListArray[2];
var check2 = {"id":"9","value":false};
doCheck(tempListArray, check1);
doCheck(tempListArray, check2);
function doCheck(array, item) {
var index = array.indexOf(item);
if (index === -1)
document.write("not in array<br/>");
else
document.write("exists at index " + index + "<br/>");
}
try to use php.js it may help while you can use same php function names and it has some useful functionalities
There is no way without iterating through the elements (that would be magic).
But, you could consider using an object instead of an array. The object would use the (presumably unique) id value as the key, and the value could have the same structure you have now (or without the redundant id property). This way, you can efficiently determine if the id already exists.
There is a possible cheat for limited cases :) and it is magic...cough cough (math)
imagine you have 3 elements:
1
2
3
and you want to know if one of these is in an array without iterating it...
we could make a number that contains a numerical flavor of the array. we do this by assigning prime numbers to the elements:
1 - 2
2 - 3
3 - 5
the array so when we add item 2 we check that the array doesn't already contain the prime associated to that item by checking (if Flavor!=0 && (Flavor%3)!=0) then adding the prime Flavor*=3;
now we can tell that the second element is in the array by looking at the number.
if Flavor!=0 && (Flavor%3)==0 // its There!
Of course this is limited to the numerical representation that can be handled by the computer. and for small array sizes (1-3 elements) it might still be faster to scan. but it's just one idea.
but the basis is pretty sound. However, this method becomes unusable if you cannot correlate elements one to one with a set of primes. You'll want to have the primes calculated in advance. and verify that the product of those is less numerical max numerical representation. (also be careful with floating-point. because they might not be able to represent the number at the higher values due to the gaps between representable values.) You probably have the best luck with an unsigned integer type.
This method will probably be too limiting. And there is something else you can do to possibly speed up your system if you don't want to iterate the entire array.
Use different structures:
dictionaries/maps/trees etc.
if your attached to the array another method can be a bloom filter. This will let you know if an element is not in your set, which can be just as useful.
I need to map specific numbers to string values. These numbers are not necessarily consecutive, and so for example I may have something like this:
var obj = {};
obj[10] = "string1";
obj[126] = "string2";
obj[500] = "string3";
If I'm doing a search like this obj[126] would it be faster for me to use an object {} or an array []?
There will be no difference. ECMAScript arrays, if sparse (that is don't have consecutive indices set) are implemented as hash tables. In any case, you are guaranteed the O(n) access time, so this shouldn't concern you at all.
I created a microbenchmark for you - check out more comprehensive test by #Bergi. On my browser object literal is a little bit slower, but not significantly. Try it yourself.
A JS-array is a object, so it should not matter what you choose.
Created a jsperf test (http://jsperf.com/array-is-object) to demonstrate this.
Definetely an object should be the best choice.
If you have such code:
var arr = [];
arr[10] = 'my value';
, your array becomes an array of 11 values
alert(arr.length); // will show you 11
, where first 10 are undefined.
Obviously you don't need an array of length 1000 to store just
var arr = [];
arr[999] = 'the string';
Also I have to notice that in programming you have to chose an appropriate classes for particular cases.
Your task is to make a map of key: value pairs and object is the better choice here.
If your task was to make an ordered collection, then sure you need an array.
UPDATE:
Answering to your question in comments.
Imagine that you have two "collections" - an array and an object. Each of them has only one key/index equal to 999.
If you need to find a value, you need to iterate through your collection.
For array you'll have 999 iterations.
For object - only one iteration.
http://jsfiddle.net/f0t0n/PPnKL/
var arrayCollection = [],
objectCollection = {};
arrayCollection[999] = 1;
objectCollection[999] = 1;
var i = 0,
l = arrayCollection.length;
for(; i < l; i++) {
if(arrayCollection[i] == 1) {
alert('Count of iterations for array: ' + i); // displays 999
}
}
i = 0;
for(var prop in objectCollection) {
i++;
if(objectCollection[prop] == 1) {
alert('Count of iterations for object: ' + i); // displays 1
}
}
Benchmark
In total:
You have to design an application properly and take into account possible future tasks which will require some different manipulations with your collection.
If you'll need your collection to be ordered, you have to chose an array.
Otherwise an object could be a better choice since the speed of access to its property is roughly same as a speed of access to array's item but the search of value in object will be faster than in sparse array.
Is it possible to turn a column of a multidimensional array to row using JavaScript (maybe Jquery)? (without looping through it)
so in the example below:
var data = new Array();
//data is a 2D array
data.push([name1,id1,major1]);
data.push([name2,id2,major2]);
data.push([name3,id3,major3]);
//etc..
Is possible to get a list of IDs from data without looping? thanks
No, it is not possible to construct an array of IDs without looping.
In case you were wondering, you'd do it like this:
var ids = [];
for(var i = 0; i < data.length; i++)
ids.push(data[i][1]);
For better structural integrity, I'd suggest using an array of objects, like so:
data.push({"name": name1, "id": id1, "major":major1});
data.push({"name": name2, "id": id2, "major":major2});
data.push({"name": name3, "id": id3, "major":major3});
Then iterate through it like so:
var ids = [];
for(var i = 0; i < data.length; i++)
ids.push(data[i].id);
JavaScript doesn't really have multidimensional arrays. What JavaScript allows you to have is an array of arrays, with which you can interact as if it was a multidimensional array.
As for your main question, no, you would have to loop through the array to get the list of IDs. It means that such an operation cannot be done faster than in linear time O(n), where n is the height of the "2D array".
Also keep in mind that arrays in JavaScript are not necessarily represented in memory as contiguous blocks. Therefore any fast operations that you might be familiar with in other low level languages will not apply. The JavaScript programmer should treat arrays as Hash Tables, where the elements are simply key/value pairs, and the keys are the indices (0, 1, 2...). You can still access/write elements in constant time O(1) (at least in modern JavaScript engines), but copying of elements will often be done in O(n).
You could use the Array map function which does the looping for you:
var ids = data.map(function(x) { return x[1] });
Unfortunately, like everything else on the web that would be really nice to use, INTERNET EXPLORER DOESN'T SUPPORT IT.
See this page for details on how the map function works:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map
The good news it that the link above provides some nice code in the "Compatibility" section which will check for the existence of Array.prototype.map and define it if it's missing.
You don't need anything special- make a string by joining with newlines, and match the middle of each line.
var data1=[['Tom Swift','gf102387','Electronic Arts'],
['Bob White','ea3784567','Culinarey Arts'],
['Frank Open','bc87987','Janitorial Arts'],
['Sam Sneer','qw10214','Some Other Arts']];
data1.join('\n').match(/([^,]+)(?=,[^,]+\n)/g)
/* returned value: (Array)
gf102387,ea3784567,bc87987
*/