How to update 2d array in jquery? - javascript

I'm trying to update 2d array but it's not working here. Please check the below code
var ksatodayvalue = [];
function pad2(n) { return n < 10 ? '0' + n : n }
var dt = new Date();
currentyear = dt.getFullYear().toString();
currentmonth = pad2(dt.getMonth() + 1);
currentday = pad2(dt.getDate());
$.getJSON(jsonrequesturl, function (data) {
$.each(data, function (index, d) {
ksatodayvalue.push("[Date.UTC("+currentyear+", "+currentmonth+", "+currentday-1+", "+d.time.split(':')[0]+", "+d.time.split(':')[1]+", "+d.time.split(':')[2]+"),3]");
});
I want array like that.
var ksatodayvalue = [[Date.UTC(2014, 03, 18, 23, 45, 00),3],[Date.UTC(2014, 03, 18, 23, 30, 00),4],[Date.UTC(2014, 03, 18, 23, 15, 00),6],[Date.UTC(2014, 03, 18, 23, 00, 00),8]];

a) You are creating a string, and probably want an object. b) You probably want values from the incoming data, and not from local variables. Try something along these lines:
ksatodayvalue.push([Date.UTC(this.currentyear, this.currentmonth, this.currentday-1, d.time.split(':')[0], d.time.split(':')[1], d.time.split(':')[2]),3]);

var ksatodayvalue = [];
$.getJSON(jsonrequesturl, function(data) {
$.each(data, function(index, d) {
ksatodayvalue.push([
Date.UTC(
this.currentyear,
this.currentmonth,
this.currentday-1,
d.time.split(':')[0],
d.time.split(':')[1],
d.time.split(':')[2]
), 3
]);
});
}).done(function() {
console.log(ksatodayvalue);
});

Related

ApexCharts.js line chart - Show zero for missing dates

I'm populating a series with "date-value pairs like this:
series: [{
name: "Price",
data:[
[1486684800000, 38],
[1486771200000, 0],
[1486857600000, 0],
[1486944000000, 0],
[1487030400000, 0],
[1487116800000, 58]]
},
But, when for instance I'm populating the series array with "missing dates" like this:
series: [{
name: "Price",
data:[
[1486684800000, 38],
[1487116800000, 58]]
},
ApexCharts will automatically fill the line, and will not fill the missing dates with zero values.
Any ideas on how to force ApexCharts to show missing dates with zero values and not "ignore" them?
I know this question is 2 years old, but I had simillar problem. My backend returns date formatted like YYYY-MM-DD, but you can change this pretty easy.
var startDate = new Date()
startDate.setDate(startDate.getDate() - 30)
var getDaysArray = function (start, end) {
for (var arr = [], dt = new Date(start); dt <= new Date(end); dt.setDate(dt.getDate() + 1)) {
const currDate = new Date(dt).toISOString().split('T')[0]
var amount = response.data.monthly_logs.find(monthlyLog => monthlyLog.created_at__date === currDate) || 0
if (amount) {
amount = amount.price
}
arr.push({ x: new Date(dt), y: amount })
}
return arr
}
var result = getDaysArray(startDate, new Date())

How to stop pushing values in a loop?

I am running the following:
function wikiText() {
console.log(JSON.stringify(JSON.parse(JSON.stringify(spacetime)), null, 4));
var url="https://en.wikipedia.org/w/api.php?action=parse&disablelimitreport=true&format=json&prop=text|langlinks&noimages=true&mobileformat=true&page="+ curTitle + "&callback=?";
$.getJSON(url,function(data){
$.each(data, function(i, item) {
spacetime[0].Title.push(curTitle);
for(var i = 0; i < dateText.length; i++) {
d += dateText[i] + ' ';
}
var words = d.split(" ");
var array = words;
var newArray = array.filter(function(v){return v!==''});
for (const word of newArray) {
if (months.has(word)) {
spacetime[0].Time.months.push(word);
} else if (+word < 32) {
spacetime[0].Time.days.push(+word);
} else if (+word < 2200) {
spacetime[0].Time.years.push(+word);
} else if (/\w+/.test(word)) {
spacetime[0].Time.suffixes.push(word);
}
}
let pattern = new RegExp('^\/wiki\/');
doSelect("Location").siblings('td').find('a').each(function(index, el) {
result = $(this).attr('href').replace(pattern, '');
countryPage();
});
};
});
});
}
And that in reality is a function which is called by another function function newQuery() {.. wikiText();
That first bit of code then runs another function function countryPage() { but this one isn't pushing spacetime[0].Time...
However I get duplicated values like:
"days": [
27,
28,
27,
28,
19,
22,
27,
28,
19,
22,
27,
28,
19,
22,
I don't understand why it is duplicating the values as if it was saving them and re-pushing them each time the function is called.
I do have a jsFiddle just be patient for a bit as it is doing a lot of parsings.(see console.log).
I need:
"days": [
27,
28,
19,
22,

Recreating a lookup table in Javascript

So I have a spreadsheet for retrieving membership rates, the columns are Age, Duration & Rate. You simply look down the age column to find the age of the customer, then when you find that age you keep heading down to match it to the correct Duration, then in the final column will be the rate. A (very) small version of that might look like this;
Age,Duration,Rate
18,10,1.33
18,11,1.5
18,12,1.8
19,10,1.4
19,11,1.65
19,12,1.88
20,10,1.48
20,11,1.73
20,12,1.98
So someone age 19, duration 11 has a rate of 1.65. Someone age 20 with a duration of 12 has a rate of 1.98 - easy!
My question is two parts, I want to convert this into a web page where someone enters the age and duration to retrieve the rate. I'm pretty sure my best option for this is a two dimensional array like so;
var array = [[18,10,1.33],[18,11,1.5],[18,12,1.8] .. and so on];
are there any better options for this?
The second question is how do I best iterate over a two dimensional array (if that ends up being the best solution)? As I touched upon before I would need to be able to have an iteration that returns the rate based on a two criteria search. I believe this would consist of a two part iteration but iteration is such a weak spot for me that trying to grasp where in the loops to put my iterations is just brain melting. I think it would look something like so;
for (var i = 0; i < array.length; i++){
for (var j = 0; j < array[i].length; j++){
//Do something... I think something like this
If array[][j] == ageImLookingFor && array[][j+1] == durationImLookingFor
then return array[][j+2] (which is the rate)
}
}
Any help, advice or ideas I would be super grateful
A better option than using an array is to use an object (or Map) with properties (keys) that correspond to valid combinations of age and duration, effectively indexing your data by that key:
var list = {
'18_10': { age: 18, duration: 10, rate: 1.33 }
'18_11': { age: 18, duration: 11, rate: 1.5 },
'18_12': { age: 18, duration: 11, rate: 1.8 },
// .. and so on
};
This way you do not have to iterate over an array (cf. your question #2), but given an age and a duration (let's say in variables that have those names), you can write this to get the matching item:
var item = list[age + '_' + duration];
Of course, you should check that age and duration are valid integer numbers and that the item could be undefined when the combination is not known.
Here is a simple snippet (without any checks) you could use to base your web form on. It builds the above mentioned object from an array having the data.
// Data in array -- will be keyed later
var arr = [
{ age: 18, duration: 10, rate: 1.33 },
{ age: 18, duration: 11, rate: 1.5 },
{ age: 18, duration: 12, rate: 1.8 },
{ age: 19, duration: 10, rate: 1.4 },
{ age: 19, duration: 11, rate: 1.65 },
{ age: 19, duration: 12, rate: 1.33 },
{ age: 20, duration: 10, rate: 1.48 },
{ age: 20, duration: 11, rate: 1.73 },
{ age: 20, duration: 12, rate: 1.98 },
];
// Build map, keyed by age/duration. It will look like:
// {
// '18_10': { age: 18, duration: 10, rate: 1.33 },
// '18_11': { age: 18, duration: 11, rate: 1.33 },
// ...etc
// }
mapByAgeDuration = {};
for (var i=0; i < arr.length; i++) {
mapByAgeDuration[arr[i].age + '_' + arr[i].duration] = arr[i];
}
// Fast retrieval function:
function getItemFor(age, duration) {
return mapByAgeDuration[age + '_' + duration];
}
// I/O
var button = document.getElementById('findRate');
var inputAge = document.getElementById('age');
var inputDuration = document.getElementById('duration');
var outputRate = document.getElementById('rate');
button.onclick = function() {
var age = inputAge.value;
var duration = inputDuration.value;
// Retrieve item for this age and duration
var item = getItemFor(age, duration);
// Output rate
outputRate.textContent = item !== undefined ? item.rate
: 'not a valid combination';
}
Age (18 - 20): <input id="age"><br>
Duration (10 - 12): <input id="duration"><br>
<button id="findRate">Find Rate</button><br>
Rate: <span id="rate"></span><br>
Q1: You can use a hash table for your lookup.
var data = [[18, 10, 1.33], [18, 11, 1.5], [18, 12, 1.8], [19, 10, 1.4], [19, 11, 1.65], [19, 12, 1.88], [20, 10, 1.48], [20, 11, 1.73], [20, 12, 1.98]],
object = {};
data.forEach(function (a) {
object[a[0]] = object[a[0]] || {};
object[a[0]][a[1]] = a[2];
});
// usage
document.write(object[19][11] + '<br>');
document.write(object[20][12] + '<br>');
document.write('<pre>' + JSON.stringify(object, 0, 4) + '</pre>');
Q2: A proposal with Array#some()
If you have sorted data, you could insert a short circuit, if the values are greater then needed.
var data = [[18, 10, 1.33], [18, 11, 1.5], [18, 12, 1.8], [19, 10, 1.4], [19, 11, 1.65], [19, 12, 1.88], [20, 10, 1.48], [20, 11, 1.73], [20, 12, 1.98]],
object = {};
function getValue(p1, p2) {
var result;
data.forEach(function (a) {
if (a[0] === p1 && a[1] === p2) {
result = a[2];
return true;
}
// short circuit for not found values
return a[0] > p1;
});
return result;
}
// usage
document.write(getValue(19, 11) + '<br>');
document.write(getValue(20, 12) + '<br>');
Another approach is to leverage on the array.filter function.
You have to reshape your data into an objects array:
var rates = [
{'age':'18','duration':'10','rate':'1.33'},
{'age':'18','duration':'11','rate':'1.5'},
{'age':'19','duration':'12','rate':'1.8'}
];
function filterRate(item){
if(item.age == this.age && item.duration == this.duration)
return item;
}
function getRateByAgeDuration(age, duration){
res = null;
try{
res = rates.filter(filterRate, {'age':age, 'duration':duration})[0].rate;
}
catch(ex){ console.log(ex);}
return res;
}
document.write(getRateByAgeDuration('18', '10'));
It depends. If you use hashes, you will have O(1) time on average, but O(n) on worst case.
If you prefer to optimize the worst case, you can use binary search to achieve O(lg n) both on average and worst cases.
function binarySearch(array, data, from=0, to=array.length) {
if(from >= to) return -1; // not found
var m = Math.floor((from+to)/2);
for(var i=0; i<data.length; ++i) {
if(data[i] < array[m][i]) return binarySearch(array, data, from, m);
if(data[i] > array[m][i]) return binarySearch(array, data, m+1, to);
}
return m;
}
var idx = binarySearch(array, [18,12]);
if(idx > -1) array[idx];

passing parameter to jquery $.grep

If I have this pice of code which checks is something already exist inside array
var array = [ 1, 5, 12, 31, 7, 69 ];
var array = $.grep(array, function(n, i) {
return (n == 112);
});
alert(array.length);
my question is simple one: How can I pass variable to this grep function and to use it instead of hardcoded 112 value inside expression?
You can just pass a variable from the outside. JavaScript's lexical scope allows for variables from the outside scope to be passed into deeper functions.
http://jsfiddle.net/ag1djcjm/
var array = [ 1, 5, 12, 31, 7, 69];
var code = 112;
// No need to declare variables twice
array = $.grep(array, function(n, i) {
return (n == code);
});
alert(array.length);
Try like this
var array = [ 1, 5, 12, 31, 7, 69 ];
var val=112;
// remove var from here it'll re-declare same variable
array = $.grep(array, function(n, i) {
return (n == val);
});
alert(array.length);
JSFIDDLE
You can do it by javascript's .filter() also
Like this
var array = [ 1, 5, 12, 31, 7, 69 ];
var val=112;
array = array.filter(function(n) { return n == val; });
alert(array.length);
JSFIDDLE
So, what you're basically trying to do, it determine if an array of numbers contains a certain number (variable).
There's no need to over-complicate this with grep. Just use indexOf:
var array = [ 1, 5, 12, 31, 7, 69 ],
search = 112,
hasNumber = array.indexOf(search) !== -1;
// Using this so that it's visible in the snippet.
document.body.textContent = hasNumber;
Just define the value you need to filter before calling $.grep function. See example below
var array = [1, 5, 12, 31, 7, 69],
filterValue = 5;
var newArray = $.grep(array, function (n, i) {
return n == filterValue;
});
Since you're redefining the array, I created a new variable newArray and assigned filtered values to that, but you can still assign it to array variable.
Code:
function filter ( data, val ) {
return $.grep(data, function ( n, i ) {
return (n == val);
});
}
Test:
var array = [ 1, 5, 12, 31, 7, 69];
var test = filter(array, 112);
alert(test.length);
Could create a function outside of $.grep() , to be called for each item in array ; could also pass additional parameters to function . Also try defining different variable names for input array , resulting array
var array = [ 1, 5, 12, 31, 7, 69 ], num = 112
, compare = function(n, i) { return n === num }
var res = $.grep(array, compare);

Add leading zeros using javascript error

How would i use javascript or jquery to add a leading zero to this?
for (im=1;im<=31;im++){
days[im]=everyDay[im];
}
Consider:
for (var t, im=1; im<=31; im++){
t = everyDay[im];
days[im] = (t < 10? 0 : '') + t;
}
Prepend it with a 0, and then take the last two characters:
var days = {};
for (im=1;im<=31;im++){
days[im] = ('0' + im).substr(-2);
}
for (im=1;im<=31;im++){
days[im] = (everyDay[im] < 10 ? '0' : '') + everyDay[im];
}
If you want leading zeros in your days array. You can create another array with days as strings like this, and use one or the other where it belongs or use parseInt() on the new array:
var days = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31],
strDays = [];
for (var i = 0, l = days.length; i < l; i++) {
strDays.push(String(days[i]).length < 2 ? '0' + days[i] : String(days[i]));
}
// `strDays` prints: ["01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"]
EDIT:
Even shorter:
var strDays = [];
for (var i = 1; i < 32; i++) {
strDays.push(('' + i).length < 2 ? '0' + i : '' + i);
}
for (var im=1;im<=31;im++){
var x = parseInt(everyDay[im]);
if(x < 10)
days[im]='0' + x;
else days[im]= x;
}

Categories