Javascript - Checking if a number is closer to 2 variables - javascript

I have 12 different numbers stored in variables, like this:
var span1 = 8.333333333;
var span2 = 16.66666667;
var span3 = 25;
var span4 = 33.33333333;
var span5 = 41.66666667;
var span6 = 50;
var span7 = 58.33333333;
var span8 = 66.66666667;
var span9 = 75;
var span10 = 83.33333333;
var span11 = 91.66666667;
var span12 = 100;
I have a function which compares a div's width to its parent's width and returns a value as a percentage (minus the % sign), for example, 48.5586. I'd like the function to check which of these span variables the result is closest to. For example, 48.5586 would return "span6" as it's closer to 50 than 41.666667.
Don't really know where to start with this one, any ideas?

Since each span is 8 1/3 % more than the previous one, which is just 100/12, you should be able to use a formula to work out which span class you need.
I worked out the following:
function spanClass(percentWidth) {
return 'span' + Math.round(percentWidth / (100/12));
}
This gives span6 for 48.5586.

The smallest difference can be found by taking the minimum of the absolute value of the difference between your input number and each variable's value.
That said, you should really use a proper data structure, like an object or an array, for mapping these strings to numbers.

Put the values in an array, then you can sort the array on the differece between the values. The smallest differece is first in the array, so that is the closest value:
var spans = [
{ span: 1, value: 8.333333333 },
{ span: 2, value: 16.66666667 },
{ span: 3, value: 25 },
{ span: 4, value: 33.33333333 },
{ span: 5, value: 41.66666667 },
{ span: 6, value: 50 },
{ span: 7, value: 58.33333333 },
{ span: 8, value: 66.66666667 },
{ span: 9, value: 75 },
{ span: 10, value: 83.33333333 },
{ span: 11, value: 91.66666667 },
{ span: 12, value: 100 }
];
var value = 48.5586;
spans.sort(function(x, y){
var a = Math.abs(value - x.value);
var b = Math.abs(value - y.value);
return a == b ? 0 : a < b ? -1 : 1;
});
alert(spans[0].span);
Demo: http://jsfiddle.net/Guffa/77Rf9/

Its better to have array. in my code also i am converting your variables to array and then processing. Eval is bad and should not be used
http://codebins.com/bin/4ldqp6b
var span1 = 8.333333333;
var span2 = 16.66666667;
var span3 = 25;
var span4 = 33.33333333;
var span5 = 41.66666667;
var span6 = 50;
var span7 = 58.33333333;
var span8 = 66.66666667;
var span9 = 75;
var span10 = 83.33333333;
var span11 = 91.66666667;
var span12 = 100;
var arr = [];
for (var i = 0; i < 12; i++) {
eval('arr[' + i + '] = span' + (i + 1));
}
function closestTo(arr, val) {
var closest = 10000,
ind = -1,
diff = 10000; // some random number
for (var i = 0; i < arr.length; i++) {
var tmp = Math.abs(val - arr[i]);
if (diff > tmp) {
diff = tmp;
closest = arr[i];
ind = i;
}
}
alert("Closesnt Number: " + closest + "\nClosest Index:" + ind + "\nclosest variable: span" + (ind + 1))
}
closestTo(arr, 50.12)

Implementation of a closest function in JavaScript. Moved all the spans into an object to make iterating over them easier. Just enumerate all the spans and keep the closest one.
var spans = {
span1: 8.333333333,
span2: 16.66666667,
span3: 25,
span4: 33.33333333,
span5: 41.66666667,
span6: 50,
span7: 58.33333333,
span8: 66.66666667,
span9: 75,
span10: 83.33333333,
span11: 91.66666667,
span12: 100
};
function closest(value) {
var delta
, lastMatch;
Object.keys(spans).forEach(function (span) {
var thisDelta;
if (!delta) {
lastMatch = span;
delta = Math.abs(value - spans[span]);
} else {
thisDelta = Math.abs(value - spans[span]);
if (thisDelta < delta) {
lastMatch = span;
delta = thisDelta;
}
}
});
return lastMatch;
}
var result = closest(48.5586);
console.log(result);
Here a working Codepen example.

Related

Pad array with missing data

I have a set of N arrays that update at various frequencies (data is pushed into them). If I have arrays that update at slower frequencies than the "fastest" arrays, those slower arrays should be padding with the previous data.
Example: 2 arrays, updating at different frequencies, over 10 seconds would look like
// fast array updates every 1 second
// after 10 seconds the data is:
let fast_array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
// slow array updates every 5 seconds
// after 10 seconds the data is:
let slow_array = [0, 1];
I would like the slower arrays to be padded as such
fast_array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
slow_array = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
And the array lengths should always be equal.
I have written an entire testable setup for this, and just cannot find out that magical formula to pad properly. Please take a look at the fiddle for an easy way to solve this! Look at function "processor"
HTML
<div>
<button id="start" type="button">
Start
</button>
<button id="stop" type="button">
Stop
</button>
</div>
<div id="feature1">
<div>
Length: <span id="feature1len"></span>
</div>
<div>
[<span id="feature1data"></span>]
</div>
</div>
<div id="feature2">
<div>
Length: <span id="feature2len"></span>
</div>
[<span id="feature2data"></span>]
</div>
</div>
JS
let startbutton = document.getElementById('start');
let stopbutton = document.getElementById('stop');
startbutton.addEventListener('click', () => {
start();
});
stopbutton.addEventListener('click', () => {
stop();
});
let feature1 = {
freq: 1,
raw_data: [],
final_data: [],
interval: null,
lenHtml: document.getElementById('feature1len'),
dataHtml: document.getElementById('feature1data')
}
let feature2 = {
freq: 5,
raw_data: [],
final_data: [],
interval: null,
lenHtml: document.getElementById('feature2len'),
dataHtml: document.getElementById('feature2data')
}
let render_interval = null;
function getRandomInt(min = 0, max = 100) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function render() {
processor(feature1);
processor(feature2);
feature1.lenHtml.innerText = feature1.final_data.length;
feature1.dataHtml.innerText = feature1.final_data.toString();
feature2.lenHtml.innerText = feature2.final_data.length;
feature2.dataHtml.innerText = feature2.final_data.toString();
}
function start() {
feature1.raw_data = [];
feature1.final_data = [];
feature2.raw_data = [];
feature2.final_data = [];
feature1.raw_data.push(getRandomInt())
feature1.interval = setInterval(() => {
feature1.raw_data.push(getRandomInt())
}, feature1.freq * 1000);
feature2.raw_data.push(getRandomInt())
feature2.interval = setInterval(() => {
feature2.raw_data.push(getRandomInt())
}, feature2.freq * 1000);
render_interval = setInterval(() => {
render();
}, 1000)
render();
}
function stop() {
clearInterval(feature1.interval);
clearInterval(feature2.interval);
clearInterval(render_interval);
}
function processor(feature) {
// determine highest frequency
let most_frequent = Math.min(feature1.freq, feature2.freq);
// determine longest length
let longest_length = Math.max(feature1.raw_data.length, feature2.raw_data.length);
// process data if needed
feature.final_data = [];
for (let i = 0; i < feature.raw_data.length; i++) {
feature.final_data.push(feature.raw_data[i]);
if(feature.freq !== most_frequent){
let max_filler = 0; //???
for(let x = 0; x < max_filler; x++){
feature.final_data.push(feature.raw_data[i]);
}
}
}
}
render();
https://jsfiddle.net/79wbnkf8/1/
You can add functions:
function lcm(x, y) {
return (!x || !y) ? 0 : Math.abs((x * y) / gcd(x, y));
}
function gcd(x, y) {
x = Math.abs(x);
y = Math.abs(y);
while(y) {
var t = y;
y = x % y;
x = t;
}
return x;
}
and then modify your process function like this:
function processor(feature) {
// determine highest frequency
let most_frequent = Math.min(feature1.freq, feature2.freq);
// determine longest length
let longest_length = Math.max(feature1.raw_data.length, feature2.raw_data.length);
let l = lcm(feature1.freq, feature2.freq);
let max_filler = l / feature1.freq;
// process data if needed
feature.final_data = [];
for (let i = 0; i < feature.raw_data.length; i++) {
if(feature.freq !== most_frequent){
//let max_filler = 0; //???
for(let x = 0; x < max_filler; x++){
feature.final_data.push(feature.raw_data[i]);
if (feature.final_data.length >=longest_length) break;
}
} else {
feature.final_data.push(feature.raw_data[i]);
}
}
}
Find the most frequent feature from your feature list
let mostFreqFeature = features.reduce((min, feature) => min.freq < feature.freq ? min : feature);
Set the interval for most frequent feature in the start function
pushItem_interval = setInterval(() => {
pushItem();
}, mostFreqFeature.freq * 1000)
Finally push items into your list
function pushItem(){
for(var i=0;i<features.length;i++){
let feature = features[i];
if(feature.freq==mostFreqFeature.freq)
feature.raw_data.push(getRandomInt())
else{
if(feature.raw_data.length<=0){
feature.raw_data.push(getRandomInt());
return;
}
if((feature.raw_data.length)% feature.freq==0)
feature.raw_data.push(getRandomInt())
else{
let lastItem = feature.raw_data[feature.raw_data.length-1];
feature.raw_data.push(lastItem)
}
}
}
}
working example jsfiddle
Hope, it will helpful for your need.

Store count of integers in order using javascript

I have string like the following:
11222233344444445666
What I would like to do is output the number followed the times it was displayed:
112433475163
Question is, I want this to be efficient. I can store this in an object as the following:
1: { id: 1, displayed: 2},
2: { id: 2, displayed: 1},
3: { id: 3, displayed: 2},
etc.
I can access this object and increment displayed.
My issues is, there is no guarantee in the order. I would like to store the keys in the order they are in the string. How do I accomplish the importance of the order in the object?
This is a proposal for run length coding with an array which holds infomation about one charcter and the count of it:
{
"char": "1",
"count": 2
},
var string = "11222233344444445666",
array = function () {
var r = [], o = {};
string.split('').forEach(function (a, i, aa) {
if (a !== aa[i - 1]) {
o[a] = { char: a, count: 0 };
r.push(o[a]);
}
o[a].count++;
});
return r;
}(string);
document.write('<pre>' + JSON.stringify(array, 0, 4) + '</pre>');
Quick solution with for loop:
var str = "7771122229933344444445666",
obj = {},
len = str.length,
val = null,
count_str = "",
key = "";
for (var i = 0; i < len; i++) {
val = str[i], key = 'k' + val;
if (!obj[key]) {
obj[key] = {'id': val, 'displayed': 1};
} else {
obj[key].displayed++;
}
}
for (var p in obj) {
count_str += obj[p]['id'] + obj[p]['displayed'];
}
console.log(count_str); // "7312249233475163"
because you have such a small set of distinct numbers, I seen no reason why you can't use a array (yeah it's not super ideal memorywise if you skip values and it becomes sparse, but for such a small subset it won't affect you enough to worry of it). Then you can use (number-1) as the index and increment that number as needed.
var counts = [];
var str = "11222233344444445666";
for(var i in str){
var index = parseInt(str[i])-1
counts[index] = (counts[index]||0)+1;
}
for(var i in counts){
var which = 1+parseInt(i);
var count = counts[i];
console.log("# of " + which +"'s: "+count);
}
https://jsfiddle.net/ga0fqpqn/
note: You shouldn't need the parseInt(i)... just +i should work but I think jsfiddle has a bug with it about it defaulting i to handle like a string.
You could store an additional array with the order of the numbers, which you only append to if the object doesn't yet contain the given number. Then once you're done counting, iterate through that array and output the number and the count from the lookup dictionary.
var chars = "1234576123452345".split("");
var order = [];
var hash = {};
chars.forEach(function(char) {
if (!hash[char]) {
hash[char] = 1;
order.push(char);
} else {
hash[char]++;
}
});
console.log(order.map(function(char) {
return char + hash[char];
}).join(""));
// "12233343537161"

Lazy.js based fibonacci to map Bacon.js interval?

I have a code to generate fib sequences with lazy.js
var fibF = function()
{
var seq = []; //build sequence array in this closure
var f = function(n)
{
var val;
if (n <= 1)
{
val = 1; // as the Fib definition in Math
}
else
{
val = seq[n - 2] + seq[n - 1]; // as the Fib definition in Math
}
seq[n] = val;
return val;
};
return f;
}();
var fibSequence = _.generate(fibF);
/* just for test
var fib_1000 =
fibSequence
.take(1000) 
.toArray(); 
console.log(fib_1000);
//[ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55,...........,4.346655768693743e+208 ]
*/
At the same time, I have a code of timer with Bacon.js
var B = require('baconjs');
var timeSequence = B
.interval(1000); //every second
timeSequence
.onValue(function()
{
console.log(require('moment')().format('MMMM Do YYYY, h:mm:ss'));
// print timestamps every second
});
Then,
I want to map the the fibSequence onto timeSequence such as
var mySequence = fibSequence.map(timeSequence);
or
var mySequence = timeSequence.map(fibSequence);
Is it possible?
If so, please show me the way.
Any workaround solution is welcome.
Thanks.
EDIT working code:
//to simplify use Natrual, instead of Fib
var _ = require('lazy.js');
var __ = require('baconjs');
var natural = function(n)
{
return n;
};
var _natural = _.generate(natural); //natural numbers
var __timer = __.interval(1000); //every second
var map_to__ = function(_seq, __seq)
{
var it = _seq.getIterator();
var sequence =
__seq
.map(function()
{
it.moveNext();
return it.current();
});
return sequence;
};
var __mappedTimer = map_to__(_natural, __timer);
__mappedTimer
.onValue(function(x)
{
console.log(x); // print every second
});
I'm not sure whether this is the intended use of iterators, but it should work:
var it = fibSequence.getIterator()
var mySequence = timeSequence.map(function() {
return it.moveNext() && it.current();
});

Conway's Game of Life - beyond the grid

Ok so there are a lot of "Conway's Game of Life" questions but this one is pretty specific. I'm going to have to throw a bunch of code at you first, break it down and show you where the issue is.
So here is my Conway's Game of Life implementation so far, right now it is limited to the console for debugging (JSfiddle - http://jsfiddle.net/georeith/C9Gyr/8/ - fire it up, open your console):
var utils = {};
/*
* utils.extend()
* - Extend initial object with all properties of following objects, objects later in the argument list take precedence.
*/
utils.extend = function(obj) {
var args = Array.prototype.slice.call(arguments, 1);
for (var i = args.length; i--;) {
for (var prop in args[i]) {
obj[prop] = args[i][prop];
}
}
return obj;
}
/*
* utils.defaults()
* - Overwrite initial object with properties of following objects only if key is present in the initial object.
*/
utils.defaults = function(obj) {
var args = Array.prototype.slice.call(arguments, 1);
for (var i = args.length; i--;) {
for (var prop in args[i]) {
if (obj.hasOwnProperty(prop)) {
obj[prop] = args[i][prop];
}
}
}
return obj;
}
/* no-wrap positioning functions */
var calcPos = {
ul: function(cell) {
return [cell.x - 1, cell.y - 1];
},
um: function(cell) {
return [cell.x, cell.y - 1];
},
ur: function(cell) {
return [cell.x + 1, cell.y - 1];
},
l: function(cell) {
return [cell.x - 1, cell.y];
},
r: function(cell) {
return [cell.x + 1, cell.y];
},
ll: function(cell) {
return [cell.x - 1, cell.y + 1];
},
lm: function(cell) {
return [cell.x, cell.y + 1];
},
lr: function(cell) {
return [cell.x + 1, cell.y + 1];
}
}
var worldDefaults = {
rows: 50,
columns: 50,
wrap: true, // left edge is mirrored on right, top edge is mirrored on bottom. Vice versa
speed: -1, // milliseconds (minimum time, waits until end of last tick to calculate from)
grid: []
}
var World = function (opts) {
this.settings = utils.defaults(worldDefaults, opts);
this.maxX = this.settings.columns - 1;
this.maxY = this.settings.rows -1;
for (var y = 0, yLen = this.settings.rows; y < yLen; ++y) {
for (var x = 0, xLen = this.settings.columns; x < xLen; ++x) {
if (y === 0) {
this.cellList.push([]);
if (this.settings.grid.length <= x) {
this.settings.grid.push([]);
}
}
var cell = new Cell();
cell.x = x;
cell.y = y;
cell.alive = !!this.settings.grid[x][y];
if (cell.alive) {
this.lifeList.push(cell);
}
var lx = (x) ? x - 1 : this.maxX;
var uy = (y) ? y - 1 : this.maxY;
var ux = (x == this.maxX) ? 0 : x + 1;
var ly = (y == this.maxY) ? 0 : y + 1;
cell.neighbourCoords = (this.settings.wrap) ?
[
[lx, uy], [x, uy], [ux, uy],
[lx, y], /*[x, y]*/ [ux, y],
[lx, ly], [x, ly], [ux, ly]
]
:
[
calcPos.ul, calcPos.um, calcPos.ur,
calcPos.l, calcPos.r,
calcPos.ll, calcPos.lm, calcPos.lr
]
;
this.cellList[x][y] = cell;
}
}
}
World.prototype.generation = 0;
World.prototype.cellList = [];
World.prototype.lifeList = [];
World.prototype.changeList = [];
World.prototype.nextTick = null;
/* Progresses the world */
World.prototype.tick = function() {
var newLifeList = [];
this.changeList = [];
// This hash goes out of scope after each tick allowing any dead shadowCells to be garbage collected
if (!this.settings.wrap) {
var shadowCellHash = {};
}
for (var i = 0, iLen = this.lifeList.length; i < iLen; ++i) {
var cell = this.lifeList[i];
if (cell.key) {
shadowCellHash[cell.key] = cell;
}
cell.neighbours = 0;
cell.lastIterated = this.generation;
for (var j = 0, jLen = cell.neighbourCoords.length; j < jLen; ++j) {
var coords;
var neighbour;
if (this.settings.wrap) {
coords = cell.neighbourCoords[j];
neighbour = this.cellList[coords[0]][coords[1]];
} else {
coords = cell.neighbourCoords[j](cell);
if (coords[0] > this.maxX || coords[0] < 0 || coords[1] > this.maxY || coords[1] < 0) {
// This neighbour is off the screen so will require a shadowCell
var key = ''+coords[0]+','+coords[1];
if (!shadowCellHash[key]) {
neighbour = shadowCellHash[key] = new ShadowCell(coords[0], coords[1]);
neighbour.neighbourCoords = cell.neighbourCoords;
} else {
neighbour = shadowCellHash[key];
}
} else {
neighbour = this.cellList[coords[0]][coords[1]];
}
}
if (neighbour.lastIterated !== this.generation) {
neighbour.neighbours = 0;
neighbour.lastIterated = this.generation;
}
if (neighbour.alive !== neighbour.changed) {
// neighbour started as alive
++cell.neighbours;
} else {
// neighbour started as dead
++neighbour.neighbours;
if (neighbour.neighbours === 3) {
neighbour.alive = true;
neighbour.changed = true;
neighbour.changeIndex = this.changeList.push(neighbour) - 1;
} else if (neighbour.neighbours === 4) {
// neighbour has reverted to dead
neighbour.alive = false;
neighbour.changed = false;
neighbour.changeIndex = -1;
this.changeList[neighbour.changeIndex] = undefined;
}
}
}
if (cell.neighbours < 2 || cell.neighbours > 3) {
cell.changed = true;
cell.alive = false;
cell.changeIndex = this.changeList.push(cell) - 1;
} else {
newLifeList.push(cell);
}
}
for (var i = 0, iLen = this.changeList.length; i < iLen; ++i) {
var cell = this.changeList[i];
if (cell !== undefined) {
cell.changeIndex = -1;
if (cell.alive) {
newLifeList.push(cell);
}
cell.update();
cell.changed = false;
}
}
this.lifeList = newLifeList;
++this.generation;
this.onTick();
var that = this;
if (this.settings.speed >= 0) {
this.nextTick = setTimeout(function() {
that.tick();
}, this.settings.speed);
}
return this;
}
World.prototype.out = function() {
var s = '';
for (var y = 0, yLen = this.settings.rows; y < yLen; ++y) {
for (var x = 0, xLen = this.settings.columns; x < xLen; ++x) {
s += (this.cellList[x][y].alive)? '\u2B1B' : '\u2B1C';
}
s += '\n';
}
s += '\u21B3 Generation: ' + this.generation + ' -- Cells: ' + this.lifeList.length + ' \u21B5';
s += '\n';
return s;
}
World.prototype.stop = function() {
this.speed = -1;
}
World.prototype.onTick = function() {
return this;
}
var Cell = function() {
return this;
}
Cell.prototype.x = 0;
Cell.prototype.y = 0;
Cell.prototype.neighbours = 0;
Cell.prototype.alive = false;
Cell.prototype.changed = false;
Cell.prototype.changeIndex = -1;
Cell.prototype.lastIterated = -1;
/*
* ShadowCell
* - non rendered cell for use in no-wrap
*/
var ShadowCell = function(x,y) {
this.x = x;
this.y = y;
this.key = ''+this.x+','+this.y;
return this;
}
ShadowCell.prototype = utils.extend({}, Cell.prototype);
ShadowCell.prototype.isShadow = true;
ShadowCell.prototype.update = function(){
return this;
};
/*
* Cell.update()
* - Update cell after tick
*/
Cell.prototype.update = function() {
this.render();
return this;
}
/*
* Cell.render()
* - Placeholder function to be overwritten by rendering engine
*/
Cell.prototype.render = function() {
return this;
}
The method I have chosen involves an array of all the cells that are alive at the start of each generation. I then iterate over each of their 8 neighbours and decide whether to create/delete them.
This works great when I pass wrap: false to the World constructor (see JSfiddle for implementation), this tells it to mirror the sides and not allow overflow. However that style of layout breaks a lot of patterns as it causes cells to come back on themselves so I also want to allow it to calculate beyond the grid.
For this purpose I created the ShadowCell class which behaves mostly the same as the Cell class (each grid cell dead or alive is an instance of it) except that the ShadowClass is only created when a non-existent cell is required outside of the grid and is offered for garbage collection the moment it is no longer required (if it is dead after each generation). Otherwise it mimics the Cell classes attributes and fits directly into the same logic that Cell does.
The issue
If you go to "generation 4" in the console output you may notice it isn't quite right...
I have narrowed this issue down to the ShadowCell implementation because this works if I provide enough padding around the shape so that it does not overflow the grid (which is when ShadowCell kicks in), although like I said earlier ShadowCell is a copy of the Cell class, it has the same attributes and gets passed in as if it was a Cell.
Because I want these to be garbage collected I do not include these in the overall grid array World.cellList... this leads me to believe the problem lies in this section of code:
// This hash goes out of scope after each tick allowing any dead shadowCells to be garbage collected
if (!this.settings.wrap) {
var shadowCellHash = {};
}
for (var i = 0, iLen = this.lifeList.length; i < iLen; ++i) {
var cell = this.lifeList[i];
if (cell.key) {
shadowCellHash[cell.key] = cell;
}
cell.neighbours = 0;
cell.lastIterated = this.generation;
for (var j = 0, jLen = cell.neighbourCoords.length; j < jLen; ++j) {
var coords;
var neighbour;
if (this.settings.wrap) {
coords = cell.neighbourCoords[j];
neighbour = this.cellList[coords[0]][coords[1]];
} else {
coords = cell.neighbourCoords[j](cell);
if (coords[0] > this.maxX || coords[0] < 0 || coords[1] > this.maxY || coords[1] < 0) {
// This neighbour is off the screen so will require a shadowCell
var key = ''+coords[0]+','+coords[1];
if (!shadowCellHash[key]) {
// ShadowCell not in hash, let's create one
neighbour = shadowCellHash[key] = new ShadowCell(coords[0], coords[1]);
neighbour.neighbourCoords = cell.neighbourCoords;
// NOTE: neighbourCoords are a set of functions that return values relative to the cell you pass to them. I am not literally giving the `ShadowCell` the same neighbour positions here.
} else {
neighbour = shadowCellHash[key];
}
} else {
// This neighbour is on screen, grab its cell.
neighbour = this.cellList[coords[0]][coords[1]];
}
}
...
Note: Alive ShadowCells will not be garbage collected as they get stored in an Array with the other cells (I am certain of this from my debugging, see the cell count in your console output and count the visible cells).
For some reason the ShadowCell class appears to cause incorrect reporting of neighbours. I have attempted to debug it by following the creation, deletion and counted neighbours of each individual cell during each generation but my brain dies before it can put it all together. For all my debugging efforts I can't see why this behaviour should occur . ShadowCell is pretty much the same as a Cell to everything else that uses it (they use the exact same position functions .etc), the fact it doesn't get rendered shouldn't be the cause of this.
For generation 4 I get the following output by logging the creation of shadow maps, I can see that each is being created once per generation (note: The class doesn't show because I used utils.extend() to create a snapshot of them):
Object {x: 5, y: -1, key: "5,-1", neighbourCoords: Array[8], neighbours: 0…}
Object {x: 6, y: -1, key: "6,-1", neighbourCoords: Array[8], neighbours: 0…}
Object {x: 7, y: -1, key: "7,-1", neighbourCoords: Array[8], neighbours: 0…}
Object {x: 4, y: -1, key: "4,-1", neighbourCoords: Array[8], neighbours: 0…}
Object {x: -1, y: 1, key: "-1,1", neighbourCoords: Array[8], neighbours: 0…}
Object {x: -1, y: 2, key: "-1,2", neighbourCoords: Array[8], neighbours: 0…}
Object {x: -1, y: 3, key: "-1,3", neighbourCoords: Array[8], neighbours: 0…}
Object {x: 5, y: -2, key: "5,-2", neighbourCoords: Array[8], neighbours: 0…}
Object {x: 6, y: -2, key: "6,-2", neighbourCoords: Array[8], neighbours: 0…}
Object {x: 7, y: -2, key: "7,-2", neighbourCoords: Array[8], neighbours: 0…}
Object {x: -1, y: 4, key: "-1,4", neighbourCoords: Array[8], neighbours: 0…}
Logged on line 152 like so:
if (!shadowCellHash[key]) {
neighbour = shadowCellHash[key] = new ShadowCell(coords[0], coords[1]);
neighbour.neighbourCoords = cell.neighbourCoords;
console.log(utils.extend({}, neighbour));
} else {
shadowCellHash is not initialized with all of the ShadowCells before you start looping through every cell looking for neighbours. When the loop checks [5,-1] for neighbors, it doesn't find [6,-1] because it's not in shadowCellHash. Since [6,-1] is not found, a new dead [6,-1] is created, and [5,-1] is not born because it does not have enough live neighbours.
I think I've resolved your issue by eagerly re-populating shadowCellHash at the beginning of each World.tick
JSFiddle
// This hash goes out of scope after each tick allowing any dead shadowCells to be garbage collected
if (!this.settings.wrap) {
var shadowCellHash = {};
for (var i = 0; i < this.lifeList.length; i++) {
var cell = this.lifeList[i];
if (cell.key) {
shadowCellHash[cell.key] = cell;
}
}
}

Find minimum value in javascript?

I want to print the minimum variable 'name' in JS. Currently it prints the minimaum value. I rather want the variable name. For eg:- In the current code, it gives me 4, but I want c. How can I do this?
<script>
function myFunction()
{
var a = 5;
var b =10;
var c = 4;
document.getElementById("demo").innerHTML=Math.min(a,b,c);
}
</script>
Working DEMO
This should do the trick:
//Push values to object
var age = {};
age.a = 5;
age.b = 10;
age.c = 4;
var min = Infinity, name;
// Loop through object to get min value and then find relevant name
for(var x in age) {
if( age[x] < min) {
min = age[x];
name = x;
}
}
console.log ( 'property name is ' + name + ' and value is ' + min );
You could put your values in an array like
var values = [
{ name: 'a', value: 5 },
{ name: 'b', value: 10 },
{ name: 'c', value: 4 }
];
and then use the filter method with the hint from Ahmad's comment:
var min_value = Math.min.apply(null, values.map(function(item) {
return item.value;
}));
var min_name = values.filter(function (item) {
return item.value == min_value;
})[0].name;
See this fiddle for a working example.
Store the values in an array of objects. Each object will contain a name and value property. Then just iterate through the values and store the lowest.
var values = [
{
"name": "a",
"value": 5
},
{"name":"b",
"value":10
},
{
"name":"c",
"value":4
}
];
function min(arr){
var minValue = {};
for(var x = 0; x < arr.length; x++){
if(arr[x].value < minValue.value || !minValue.value){
minValue = arr[x];
}
}
return minValue.name;
};
document.getElementById("demo").innerHTML = min(values);
JS Fiddle: http://jsfiddle.net/AgMbW/
You can do this way:
var obj = {"names":["a","b","c"], "values":[5,10,4]}
var min = Math.min.apply( Math, obj["values"] );
var result = obj["names"][obj["values"].indexOf(min)];
document.getElementById("demo").innerHTML=result;
Here the fiddle: http://jsfiddle.net/eUcug/
Way 1 :
var x = 5;var getName = function(value){if(value === 5) return 'x'; else return null}
Way 2 :
NameValue.getName = function(value){for(i = 1;i<=2;i++){if(this["val" + i].value === value) {return this["val" + i].name;break;}console.log(this["val" + i]);}return null;}NameValue.val2 = {name : 'y',value : 1};NameValue.prototype.add({name : 'x',value : 10})
NameValue.getName(10); //return "x"
I hope you can understand how to find the variable name.

Categories