I have this array declared like this :
var gamme =
[
["A"],
["A♯","B♭"],
["B","C♭"],
["C","B♯"],
["C♯","D♭"],
["D"],
["D♯","E♭"],
["E","F♭"],
["F","E♯"],
["F♯","G♭"],
["G"],
["G♯","A♭"],
];
using this array, I’m generating another array.
I want temperamentEgal to look like this :
for example :
temperamentEgal[10] = [103.82617439498631, ["G♯","A♭"]]
temperamentEgal[25] = [233.08188075904502, ["A♯","B♭"]]
so this is what I do :
base = pow(2,1/12); // 2^(1/12)
for (i=0; i<12*octaves; i++) // octaves = 6
{
temperamentEgal[i] = []
temperamentEgal[i][0] = 55*pow(base,i); // = 138.6
temperamentEgal[i][1] = gamme[i%12]; // = ["C♯","D♭"]
console.log("gamme["+i%12+"] = " + gamme[i%12]);
for (j=0; j<temperamentEgal[i][1].length; j++)
{
var octaveNote = 1+i/12;
octaveNote = floor(octaveNote);
temperamentEgal[i][1][j] += str(octaveNote);
}
}
As you can see, at no point I’m changing the value of gamme
nonetheless, as the loop progresses, I’m getting this from the console.log :
gamme[0] = A
gamme[1] = A♯,B♭
gamme[2] = B,C♭
gamme[3] = C,B♯
gamme[4] = C♯,D♭
gamme[5] = D
gamme[6] = D♯,E♭
gamme[7] = E,F♭
gamme[8] = F,E♯
gamme[9] = F♯,G♭
gamme[10] = G
gamme[11] = G♯,A♭
gamme[0] = A1
gamme[1] = A♯1,B♭1
gamme[2] = B1,C♭1
gamme[3] = C1,B♯1
gamme[4] = C♯1,D♭1
gamme[5] = D1
gamme[6] = D♯1,E♭1
gamme[7] = E1,F♭1
gamme[8] = F1,E♯1
gamme[9] = F♯1,G♭1
gamme[10] = G1
gamme[11] = G♯1,A♭1
If I comment out temperamentEgal[i][1][j] += str(octaveNote); it’s not happening anymore.
Why would changing the value of temperamentEgal[i][1] change the value of gamme[i%12] as well ?
while you don't change gamme, you change the anonymous arrays referenced on this line:
temperamentEgal[i][1] = gamme[i%12];
both right side and left side of this assignment now point to the same Array objects - if you want to modify a copy of the Array, you should copy the values of the Array, not the reference to the Array object:
ES5: temperamentEgal[i][1] = gamme[i%12].slice();
ES6: temperamentEgal[i][1] = [...gamme[i%12]] using spread operator
Related
I have a method in Vuejs which updates a set of variables based on a selection.
methods: {
updateChart(){
this.chart1.series[1].data = [this.$store.state.selectedcities[0].value[1]];
this.chart1.series[2].data = [this.$store.state.selectedcities[0].value[2]];
this.chart1.series[3].data = [this.$store.state.selectedcities[0].value[3]];
this.chart1.series[5].data = [this.$store.state.selectedcities[0].value[5]];
this.chart1.series[7].data = [this.$store.state.selectedcities[0].value[7]];
this.chart1.series[8].data = [this.$store.state.selectedcities[0].value[8]];
this.chart1.series[9].data = [this.$store.state.selectedcities[0].value[9]];
this.chart1.series[11].data = [this.$store.state.selectedcities[0].value[11]];
this.chart1.series[12].data = [this.$store.state.selectedcities[0].value[12]];
this.chart1.series[13].data = [this.$store.state.selectedcities[0].value[13]];
this.chart1.series[14].data = [this.$store.state.selectedcities[0].value[14]];
this.chart1.series[16].data = [this.$store.state.selectedcities[0].value[16]];
this.chart1.series[17].data = [this.$store.state.selectedcities[0].value[17]];
this.chart1.series[18].data = [this.$store.state.selectedcities[0].value[18]];
this.chart1.series[20].data = [this.$store.state.selectedcities[0].value[20]];
this.chart1.series[21].data = [this.$store.state.selectedcities[0].value[21]];
this.chart1.series[22].data = [this.$store.state.selectedcities[0].value[22]];
}
The problem is that it looks rather verbose, so I wonder if I can run a for loop there that iterates through those numbers. The thing is that the numbers aren't sequenced. I mean the series runs as {1,2,3,5,7,8,9,11,12,13,14,16,17,18,20,21,22}.
In the end what I'm searching for is something that looks like this:
methods:{
updateChart(){
var n = {1,2,3,5,7,8,9,11,12,13,14,16,17,18,20,21,22}
for(i in n){
this.chart1.series[i].data = [this.$store.state.selectedcities[0].value[i]];
}
}
}
I'm not really sure how to do it as I'm quite new to javascript.
EDIT:
Is it possible to add a nested foreach with this method?
For example:
var k = [1,3,6]
var n = [1,2,3,5,7,8,9,11,12,13,14,16,17,18,20,21,22]
n.forEach(i=>{
this.chart[k].series[i].data = [this.$store.state.selectedcities[k].value[i]];
})
Note that k was added to the formula and that n is child of k. So for each k it should run the series of n.
n should be an array and loop through it using forEach method like :
var n = [1,2,3,5,7,8,9,11,12,13,14,16,17,18,20,21,22]
n.forEach(i=>{
this.chart1.series[i].data = [this.$store.state.selectedcities[0].value[i]];
})
ُEDIT
var m = [1,3,6]
m.forEach(k=>{
n.forEach(i=>{
this.chart[k].series[i].data =
[this.$store.state.selectedcities[k].value[i]];
})
})
You could use foreach.
updateChart() {
var n = [1,2,3,5,7,8,9,11,12,13,14,16,17,18,20,21,22];
n.forEach(number => {
this.chart1.series[number].data = [this.$store.state.selectedcities[0].value[number]];
});
}
What is the best way to consolidate this code? As it is, it works perfectly, but it needs to go up to maybe 40-50 items long, so it needs to be shortened dramatically, (I assume, with a for loop).
I'm pretty much a novice when it comes to Javascript, and trying to add arrays to an array with a loop is confusing me immensely.
The "vac1.", "vac2." ...etc, variables are used later on in the code to add pointers onto a Google Maps map.
var x = count.count; // x = a value that changes (between 1 & 50)
if(x == 1){
locations = [
[vac1.vacancy_title, vac1.vacancy_latlng, vac1.vacancy_url, vac1.vacancy_location]
];
}
if(x == 2){
locations = [
[vac1.vacancy_title, vac1.vacancy_latlng, vac1.vacancy_url, vac1.vacancy_location],
[vac2.vacancy_title, vac2.vacancy_latlng, vac2.vacancy_url, vac2.vacancy_location]
];
}
if(x == 3){
locations = [
[vac1.vacancy_title, vac1.vacancy_latlng, vac1.vacancy_url, vac1.vacancy_location],
[vac2.vacancy_title, vac2.vacancy_latlng, vac2.vacancy_url, vac2.vacancy_location],
[vac3.vacancy_title, vac3.vacancy_latlng, vac3.vacancy_url, vac3.vacancy_location]
];
}
...etc etc...
I have tried using a for loop, but it doesn't work and I have no idea if I am anywhere close to figuring out how to do it correctly.
var x = count.count;
locations = [];
array = [];
for (i = 0; i < x; i++) {
array = [vac[i].vacancy_title, vac[i].vacancy_latlng, vac[i].vacancy_url, vac[i].vacancy_location];
locations.push(array);
}
Any help or advice would be greatly appreciated!
Thank you.
You need to consider them as a string:
var x = 5;
locations = [];
array = [];
for (i = 1; i <= x; i++) {
array = ['vac'+i+'.vacancy_title', 'vac'+i+'.vacancy_latlng', 'vac'+i+'.vacancy_url', 'vac'+i+'.vacancy_location'];
locations.push(array);
}
console.log(locations);
Create an array vac and use your previous code :
var x = count.count;
locations = [],
array = [],
vac = [ /* vac1, vac2, ...., vacn */ ];
for (i = 0; i < x; i++) {
array = [vac[i].vacancy_title, vac[i].vacancy_latlng, vac[i].vacancy_url, vac[i].vacancy_location];
locations.push(array);
}
You could use eval for the variable name and build an new array with another array for the wanted keys.
Basically you should reorganize yor program to use a solution without eval. An array could help. It is made for iteration.
var x = count.count,
i,
keys = ['vacancy_title', 'vacancy_latlng', 'vacancy_url', 'vacancy_location'],
locations = [];
object;
for (i = 1; i <= x; i++) {
object = eval('vac' + i);
locations.push(keys.map(function (k) { return object[k]; }));
}
Group the vac* elements in an array and then use slice to cut out as many as you want, then use map to generate the result array:
var vacs = [vac1, vac2 /*, ...*/]; // group the vacs into one single array
var x = count.count; // x is the number of vacs to generate
var locations = vacs.slice(0, x).map(function(vac) { // slice (cut out) x elements from the arrays vacs then map the cut-out array into your result array
return [vac.vacancy_title, vac.vacancy_latlng, vac.vacancy_url, vac.vacancy_location];
});
Because any global variable is a property of the global object :
var vac1 = "whatever";
console.lof(window.vac1); // => logs "whatever"
console.lof(window["vac1"]); // => accessed as an array, logs "whatever" too
You could use the global object and access it as an array to look for your vac1, vac2, vac3 variables :
var x = count.count, i;
locations = [],
array = [],
var globalObject = window; // or whatever the global object is for you
var vac; // this will be used to store your vac1, vac2, etc.
for (i = 0; i < x; i++) {
vac = globalObject["vac"+i]; // the "vac" + i variable read from the global object
if (vac !== undefined) {
array = [vac.vacancy_title, vac.vacancy_latlng, vac.vacancy_url, vac.vacancy_location];
locations.push(array);
}
}
I have an array named globalArrayAllTrades as you see below. I simply like to INVERT the date in a new copy of the array. So I loop through, create a new object and add it to the new array - simple.
Then function does exactly as expected. BUT if the array contains too many objects the code fails with a "FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory".
My laptop has 8 GB of memory...When the NODEJS process crashes it uses about 1.5 GB and about 70% of of totally amount of available memory is used.
I do run the NODEJS app with the parameter: --max_old_space_size=5000 which normally fixes every thing. But not this one and i have tried MANY different ways to code the same function - BUT each and every time - it fails...unless the original array is smaller.
How can I fix this issue?
function invertTrades(){
var original = globalArrayAllTrades.slice();
globalArrayAllTrades.length = 0;
globalListAllTrades.length = 0;
for(var i = 0; i < original.length; i++){
var objS = original[i];
var objE = original[original.length-1-i];
var objInv = new TradePoint(objS.number, objS.matchdate, objE.price, objE.size, objE.issell);
globalArrayAllTrades.push(objInv);
globalListAllTrades[objInv.matchdate] = objInv;
}
}
You can save some memory by making original just contain the properties you need to invert, not the whole TradePoint object. Then you don't need to construct new TradePoint objects, you can modify them in place.
var original = globalArrayAllTrades.map(function(trade) {
return {
trade.price,
trade.size,
trade.issell
};
}).reverse();
globalArrayAllTrades.forEach(function(trade, i) {
trade.price = original[i].price;
trade.size = original[i].size;
trade.issell = original[i].issell;
});
And since all the objects were modified in place, there's no need to update globalListAllTrades.
Another way is to swap the price, size, and issell properties in place between the pairs of elements:
var midpoint = Math.floor(globalArrayAllTrade.length/2);
for (var i = 0; i < midpoint; i++) {
var objS = globalArrayAllTrades[i];
var objE = globalArrayAllTrades[globalArrayAllTrades.length-1-i];
var temp = objS.price;
objS.price = objE.price;
objE.price = temp;
temp = objS.size;
objS.size = objE.size;
objE.size = temp;
temp = objS.issell;
objS.issell = objE.issell;
objE.issell = temp;
}
Have you considered just doing this?
// Copy array and then reverse it
var newArray = [].concat(original).reverse();
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse
I would suggest avoiding to copy that array:
function getInverse(i) {
var objS = globalArrayAllTrades[i];
var objE = globalArrayAllTrades[globalArrayAllTrades.length-1-i];
var objInv = new TradePoint(objS.number, objS.matchdate, objE.price, objE.size, objE.issell);
globalListAllTrades[objInv.matchdate] = objInv;
return objInv;
}
function invertTrades(){
globalListAllTrades.length = 0;
for (var i = 0, l = Math.floor(globalArrayAllTrades.length/2); i < l; i++) {
var j = globalArrayAllTrades.length-1-i;
var a = getInverse(i);
var b = getInverse(j);
globalArrayAllTrades[i] = a;
globalArrayAllTrades[j] = b;
}
}
--Solved by Elliot B. Thanks!
May also take int account the other modifications.
Here is the result. Thanks, everyone, for the speedy answers! http://dl.dropbox.com/u/18785762/Rust/index.html
I'm writing a game in javascript, and I want to keep the files for matching block IDs to files in a seperate .js file from the map compiler, so that I can edit things easily. However, the IDs are stored in an array, and I can't seem to get it to use the return function properly. Any help?
drawmap.js:
function drawmap() {
var images = BlockID();
var level = [
"ssssssssssssssssssssss",
"sgggggggggCCCCCdddddss",
"ssssssssss sssssss"
];
var top = 100;
var left = 100;
var mytop = top;
var myleft = left;
for (y=0; y<level.length; ++y) {
var row = level[y];
for (x=0; x < row.length; ++x) {
var c = row.charAt(x);
if(c != ' ') {
img_create(images[c], mytop, myleft);
}
mytop += 13;
myleft += 27;
}
mytop = top + (y+1)*13;
myleft = left - (y+1)*27;
}
}
mapread.js:
function BlockID() {
var IDs = new Array();
images['s'] = "Images/Block_01.png";
images['g'] = "Images/Block_02.png";
images['C'] = "Images/Block_03.png";
images['d'] = "Images/Block_04.png";
return IDs;
}
At a minimum, change this:
function BlockID() {
var IDs = new Array();
images['s'] = "Images/Block_01.png";
images['g'] = "Images/Block_02.png";
images['C'] = "Images/Block_03.png";
images['d'] = "Images/Block_04.png";
return IDs;
}
To this:
function BlockID() {
var IDs = new Object();
IDs['s'] = "Images/Block_01.png";
IDs['g'] = "Images/Block_02.png";
IDs['C'] = "Images/Block_03.png";
IDs['d'] = "Images/Block_04.png";
return IDs;
}
There are a couple fixes to point out. First, images is not defined in your original function, so assigning property values to it will throw an error. We correct that by changing images to IDs. Second, you want to return an Object, not an Array. An object can be assigned property values akin to an associative array or hash -- an array cannot. So we change the declaration of var IDs = new Array(); to var IDs = new Object();.
After those changes your code will run fine, but it can be simplified further. You can use shorthand notation (i.e., object literal property value shorthand) to create the object and return it immediately:
function BlockID() {
return {
"s":"Images/Block_01.png"
,"g":"Images/Block_02.png"
,"C":"Images/Block_03.png"
,"d":"Images/Block_04.png"
};
}
Your BlockID function uses the undefined variable images, which will lead to an error. Also, you should not use an Array here - JavaScripts key-value-maps are plain objects:
function BlockID() {
return {
"s": "Images/Block_01.png",
"g": "Images/Block_02.png",
"C": "Images/Block_03.png",
"d": "Images/Block_04.png"
};
}
neater:
function BlockID() {
return {
"s":"Images/Block_01.png",
"g":"Images/Block_02.png",
"C":"Images/Block_03.png",
"d":"Images/Block_04.png"
}
}
or just
var images = {
"s":"Images/Block_01.png",
"g":"Images/Block_02.png",
"C":"Images/Block_03.png",
"d":"Images/Block_04.png"
}
Taking in consideration that in JavaScript Array is object too this can be written as:
function BlockID() {
return new Array(
"Images/Block_01.png",
"Images/Block_02.png",
"Images/Block_03.png",
"Images/Block_04.png"
);
}
This code will display content of array in browser's window
window.onload=function(){
var s="";
var ar = BlockID(); //function return array
for(el in ar){
s+=ar[el]+"</br>";
}
document.body.innerHTML=s;
};
I am running a script that loads an image from an array at random each time the page is refreshed. An undesirable feature of this script, and every other script like it that I have seen online, is that though there are over 100 images in the array, it often loads the same image a number of times before all of the images in the array have been viewed.
I would like to alter the script to prevent the same image from being called twice before all of the images in the array have been viewed. If an entirely different approach than the one I have taken here is preferable, please let me know. Also, my understanding of javascript is shakey so a thorough explanation of how to correct this issue would be most helpful.
Thanks in advance
Here is the page source:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<link href="css/styles.css" rel="stylesheet" type="text/css">
<!--[if IE]><link href="css/ie-styles.css" rel="stylesheet" type="text/css"><![endif]-->
<script type="text/javascript">
<!--
var xoxo = new Array(); // Array to hold filenames
xoxo[0] = "images/portrait/fpo/01.jpg"
xoxo[1] = "images/portrait/fpo/02.jpg"
xoxo[2] = "images/portrait/fpo/03.jpg"
xoxo[3] = "images/portrait/fpo/04.jpg"
xoxo[4] = "images/portrait/fpo/05.jpg"
xoxo[5] = "images/portrait/fpo/06.jpg"
xoxo[6] = "images/portrait/fpo/07.jpg"
xoxo[7] = "images/portrait/fpo/08.jpg"
xoxo[8] = "images/portrait/fpo/09.jpg"
xoxo[9] = "images/portrait/fpo/10.jpg"
xoxo[10] = "images/portrait/fpo/11.jpg"
xoxo[11] = "images/portrait/fpo/12.jpg"
xoxo[12] = "images/portrait/fpo/13.jpg"
xoxo[13] = "images/portrait/fpo/14.jpg"
xoxo[14] = "images/portrait/fpo/15.jpg"
xoxo[15] = "images/portrait/fpo/16.jpg"
xoxo[16] = "images/portrait/fpo/17.jpg"
xoxo[17] = "images/portrait/fpo/18.jpg"
xoxo[18] = "images/portrait/fpo/19.jpg"
xoxo[19] = "images/portrait/fpo/20.jpg"
xoxo[20] = "images/portrait/fpo/21.jpg"
xoxo[21] = "images/portrait/fpo/22.jpg"
xoxo[22] = "images/portrait/fpo/23.jpg"
xoxo[23] = "images/portrait/fpo/24.jpg"
xoxo[24] = "images/portrait/fpo/25.jpg"
xoxo[25] = "images/portrait/fpo/26.jpg"
xoxo[26] = "images/portrait/fpo/27.jpg"
xoxo[27] = "images/portrait/fpo/28.jpg"
xoxo[28] = "images/portrait/fpo/29.jpg"
xoxo[29] = "images/portrait/fpo/30.jpg"
xoxo[30] = "images/portrait/fpo/31.jpg"
xoxo[31] = "images/portrait/fpo/32.jpg"
xoxo[32] = "images/portrait/fpo/33.jpg"
xoxo[33] = "images/portrait/fpo/34.jpg"
xoxo[34] = "images/portrait/fpo/35.jpg"
xoxo[35] = "images/portrait/fpo/36.jpg"
xoxo[36] = "images/portrait/fpo/37.jpg"
xoxo[37] = "images/portrait/fpo/38.jpg"
xoxo[38] = "images/portrait/fpo/39.jpg"
xoxo[39] = "images/portrait/fpo/40.jpg"
xoxo[40] = "images/portrait/fpo/41.jpg"
xoxo[41] = "images/portrait/fpo/42.jpg"
xoxo[42] = "images/portrait/fpo/43.jpg"
xoxo[43] = "images/portrait/fpo/44.jpg"
xoxo[44] = "images/portrait/fpo/45.jpg"
xoxo[45] = "images/portrait/fpo/46.jpg"
xoxo[46] = "images/portrait/fpo/47.jpg"
xoxo[47] = "images/portrait/fpo/48.jpg"
xoxo[48] = "images/portrait/fpo/49.jpg"
xoxo[49] = "images/portrait/fpo/50.jpg"
xoxo[50] = "images/portrait/fpo/51.jpg"
xoxo[51] = "images/portrait/fpo/52.jpg"
xoxo[52] = "images/portrait/fpo/53.jpg"
xoxo[53] = "images/portrait/fpo/54.jpg"
xoxo[54] = "images/portrait/fpo/55.jpg"
xoxo[55] = "images/portrait/fpo/56.jpg"
xoxo[56] = "images/portrait/fpo/57.jpg"
xoxo[57] = "images/portrait/fpo/58.jpg"
xoxo[58] = "images/portrait/fpo/59.jpg"
xoxo[59] = "images/portrait/fpo/60.jpg"
xoxo[60] = "images/portrait/fpo/61.jpg"
xoxo[61] = "images/portrait/fpo/62.jpg"
xoxo[62] = "images/portrait/fpo/63.jpg"
xoxo[63] = "images/portrait/fpo/64.jpg"
xoxo[64] = "images/portrait/fpo/65.jpg"
xoxo[65] = "images/portrait/fpo/66.jpg"
xoxo[66] = "images/portrait/fpo/67.jpg"
xoxo[67] = "images/portrait/fpo/68.jpg"
xoxo[68] = "images/portrait/fpo/69.jpg"
xoxo[69] = "images/fashion/fpo/01.jpg"
xoxo[70] = "images/fashion/fpo/02.jpg"
xoxo[71] = "images/fashion/fpo/03.jpg"
xoxo[72] = "images/fashion/fpo/04.jpg"
xoxo[73] = "images/fashion/fpo/05.jpg"
xoxo[74] = "images/fashion/fpo/06.jpg"
xoxo[75] = "images/fashion/fpo/07.jpg"
xoxo[76] = "images/fashion/fpo/08.jpg"
xoxo[77] = "images/fashion/fpo/09.jpg"
xoxo[78] = "images/fashion/fpo/10.jpg"
xoxo[79] = "images/fashion/fpo/11.jpg"
xoxo[80] = "images/fashion/fpo/12.jpg"
xoxo[81] = "images/fashion/fpo/13.jpg"
xoxo[82] = "images/fashion/fpo/14.jpg"
xoxo[83] = "images/fashion/fpo/15.jpg"
xoxo[84] = "images/fashion/fpo/16.jpg"
xoxo[85] = "images/fashion/fpo/17.jpg"
xoxo[86] = "images/fashion/fpo/18.jpg"
xoxo[87] = "images/fashion/fpo/19.jpg"
xoxo[88] = "images/fashion/fpo/20.jpg"
xoxo[89] = "images/fashion/fpo/21.jpg"
xoxo[90] = "images/fashion/fpo/22.jpg"
xoxo[91] = "images/fashion/fpo/23.jpg"
xoxo[92] = "images/fashion/fpo/24.jpg"
xoxo[93] = "images/fashion/fpo/25.jpg"
xoxo[94] = "images/fashion/fpo/26.jpg"
xoxo[95] = "images/fashion/fpo/27.jpg"
xoxo[96] = "images/fashion/fpo/28.jpg"
xoxo[97] = "images/fashion/fpo/29.jpg"
xoxo[98] = "images/fashion/fpo/30.jpg"
xoxo[99] = "images/fashion/fpo/31.jpg"
xoxo[100] = "images/fashion/fpo/32.jpg"
xoxo[101] = "images/fashion/fpo/33.jpg"
xoxo[102] = "images/fashion/fpo/34.jpg"
xoxo[103] = "images/fashion/fpo/35.jpg"
xoxo[104] = "images/fashion/fpo/36.jpg"
xoxo[105] = "images/fashion/fpo/37.jpg"
xoxo[106] = "images/fashion/fpo/38.jpg"
xoxo[107] = "images/fashion/fpo/39.jpg"
xoxo[108] = "images/fashion/fpo/40.jpg"
xoxo[109] = "images/fashion/fpo/41.jpg"
xoxo[110] = "images/fashion/fpo/42.jpg"
xoxo[111] = "images/fashion/fpo/43.jpg"
xoxo[112] = "images/fashion/fpo/44.jpg"
xoxo[113] = "images/fashion/fpo/45.jpg"
xoxo[114] = "images/fashion/fpo/46.jpg"
xoxo[115] = "images/fashion/fpo/47.jpg"
xoxo[116] = "images/fashion/fpo/48.jpg"
xoxo[117] = "images/fashion/fpo/49.jpg"
xoxo[118] = "images/fashion/fpo/50.jpg"
xoxo[119] = "images/fashion/fpo/51.jpg"
xoxo[120] = "images/fashion/fpo/52.jpg"
xoxo[121] = "images/fashion/fpo/53.jpg"
xoxo[122] = "images/fashion/fpo/54.jpg"
xoxo[123] = "images/fashion/fpo/55.jpg"
xoxo[124] = "images/fashion/fpo/56.jpg"
xoxo[125] = "images/fashion/fpo/57.jpg"
xoxo[126] = "images/fashion/fpo/58.jpg"
xoxo[127] = "images/fashion/fpo/59.jpg"
xoxo[128] = "images/fashion/fpo/60.jpg"
xoxo[129] = "images/fashion/fpo/61.jpg"
xoxo[130] = "images/fashion/fpo/62.jpg"
xoxo[131] = "images/fashion/fpo/63.jpg"
xoxo[132] = "images/fashion/fpo/64.jpg"
xoxo[133] = "images/fashion/fpo/65.jpg"
xoxo[134] = "images/fashion/fpo/66.jpg"
xoxo[135] = "images/fashion/fpo/67.jpg"
xoxo[136] = "images/fashion/fpo/68.jpg"
xoxo[137] = "images/fashion/fpo/69.jpg"
xoxo[138] = "images/children/fpo/01.jpg"
xoxo[139] = "images/children/fpo/02.jpg"
xoxo[140] = "images/children/fpo/03.jpg"
xoxo[141] = "images/children/fpo/04.jpg"
xoxo[142] = "images/children/fpo/05.jpg"
xoxo[143] = "images/children/fpo/06.jpg"
xoxo[144] = "images/children/fpo/07.jpg"
xoxo[145] = "images/children/fpo/08.jpg"
xoxo[146] = "images/children/fpo/09.jpg"
xoxo[147] = "images/children/fpo/10.jpg"
xoxo[148] = "images/children/fpo/11.jpg"
xoxo[149] = "images/children/fpo/12.jpg"
xoxo[150] = "images/children/fpo/13.jpg"
xoxo[151] = "images/children/fpo/14.jpg"
xoxo[152] = "images/children/fpo/15.jpg"
xoxo[153] = "images/children/fpo/16.jpg"
xoxo[154] = "images/children/fpo/17.jpg"
xoxo[155] = "images/children/fpo/18.jpg"
xoxo[156] = "images/children/fpo/19.jpg"
xoxo[157] = "images/children/fpo/20.jpg"
xoxo[158] = "images/children/fpo/21.jpg"
xoxo[159] = "images/children/fpo/22.jpg"
xoxo[160] = "images/children/fpo/23.jpg"
xoxo[161] = "images/children/fpo/24.jpg"
xoxo[162] = "images/children/fpo/25.jpg"
xoxo[163] = "images/children/fpo/26.jpg"
xoxo[164] = "images/children/fpo/27.jpg"
xoxo[165] = "images/children/fpo/28.jpg"
xoxo[166] = "images/children/fpo/29.jpg"
xoxo[167] = "images/children/fpo/30.jpg"
xoxo[168] = "images/children/fpo/31.jpg"
xoxo[169] = "images/children/fpo/32.jpg"
xoxo[170] = "images/children/fpo/33.jpg"
xoxo[171] = "images/children/fpo/34.jpg"
xoxo[172] = "images/children/fpo/35.jpg"
xoxo[173] = "images/children/fpo/36.jpg"
xoxo[174] = "images/children/fpo/37.jpg"
function pickRandom(range) {
if (Math.random)
return Math.round(Math.random() * (range-1));
else {
var now = new Date();
return (now.getTime() / 1000) % range;
}
}
// Write out an IMG tag, using a randomly-chosen image name.
var choice = pickRandom(xoxo.length);
// -->
</script>
<div class="menu">
<a style="color:#000000" href="index.html">Index</a><br>
Portrait<br>
Fashion<br>
Children<br>
Clients<br>
Contact<br>
</div>
<table cellpadding="0" cellspacing="0" border="0" height="100%" width="100%">
<tr valign="middle"><td align="center">
<script type="text/javascript">document.writeln('<img src="'+xoxo[choice]+'" >');</script>
</td></tr>
</table>
If you really wanted to make sure an image is never repeated until all of them have been shown, you can store a list of indices you have already displayed using localstorage.
You can use
localStorage['viewedItems'] = JSON.stringify(viewedItems)
to save an array to localstorage, where viewedItems (the second one) is the name of the array containing all of the indices you have already shown. You can then use
JSON.parse(localStorage['viewedItems'])
to retrieve the array on every page load to see what you've already displayed. Every time, you're reading it, adding an index (pick an index until you get one not in this array), writing it. Once the size of the array has reached the number of images you have, clear it and start over.
Updated, and hopefully more detailed, explanation
First you want to load the viewedItems array from localStorage. Then pick a random number as you already do, and see if that number exists in viewedItems. You can do this using indexOf. The select a number and check if exists code will be in a loop so you keep doing it until you find a number that doesn't exist in your array. Show that index. You can then use the push method to add this index to your viewedItems array. Finally, save the viewedItems array to localStorage.
Pseudocode
load viewedItems from localStorage
do
r = random number
while viewedItems.indexOf(r) > -1
show xoxo[r]
viewedItems.push(r)
save viewedItems to localStorage
Since JavaScript numbers can hold integers of over 50 bits, 3 numbers could keep track of 150 files.
The following code provides functions for creating, manipulating and interrogating a data structure consisting of an array of 50 bit numbers:
function Set (len) {
// Establish an array of sufficient 50 bit numbers to hold len bits
this.bits = new Array (Math.floor ((len + 49) / 50));
this.len = len;
// Clear all numbers
for (var i = this.bits.length; i--;)
this.bits[i] = 0;
}
Set.prototype.full = function () {
// Check if all bits of the set at 1
// First check the relevant bits of the last word
if (this.bits[this.bits.length - 1] === Math.pow (2, this.len + 1) - 1)
// Then chec tat all remaining numbers are full
for (var i = this.bits.length - 1; i--;)
if (bits[i] !== Math.pow (2, 51) - 1)
return false;
return true;
}
Set.prototype.check = function (n) {
// Return value (0 or 1) of bit n of the set
var m = n % 50;
return Math.floor (this.bits [(n - m) / 50] / Math.pow (2, m)) & 1;
}
Set.prototype.add = function (n) {
// Set bit n of the set to 1 (unless it is already 1)
if (!this.check (n)) {
var m = n % 50;
this.bits [(n - m) / 50] += Math.pow (2, m);
return true;
}
return false;
}
Set.prototype.remove = function (n) {
// Set bit of the set to 0 (unless it is already 0)
if (this.check (n)) {
var m = n % 50;
this.bits [(n - m) / 50] -= Math.pow (2, m);
return true;
}
return false;
}
Set.prototype.clear = function () {
// Clear all bitsof the set to 0
for (var i = this.bits.length; i--;)
bits[i] = 0;
}
This may not be the best solution, but give it a spin. Have a second array just as big as the first, but have it store booleans. The indexes from the second array correspond to the indexes from the first array. So when the script gives 24 as the random number, it should return the 25th image from the xoxo array, AND it should set the 25th element in the second array to false. For example:
// assume isAvailable is the array that holds the bools
function pickRandom(range) {
checkAvailabilities(); // checks to see if all the images have been used
if (Math.random) {
while (true) {
var choice = Math.round(Math.random() * (range-1));
if (isAvailable[choice]) {
isAvailable[choice] = false;
return choice;
}
}
}
else {
var now = new Date();
return (now.getTime() / 1000) % range;
}
}
function checkAvailabilities()
{
// check if there are still some images that haven't been chosen
for (var i = 0; i < isAvailable.length; i++)
if (isAvailable[i])
return;
// all the images have been used, so make all of them available again
for (var i = 0; i < isAvailable.length; i++)
isAvailable[i] = true;
}