I’m currently trying to pull dates from the DOM (formatted as 1563595200) into an array in Javascript. The next step is to sort the array properly from closest date to farthest away and cannot figure it out.
Example of element:
<span class="meta-item date">1563595200</span>
Javascript:
var className = document.getElementsByClassName('date');
var classnameCount = className.length;
var IdStore = new Array();
for(var j = 0; j < classnameCount; j++){
var dateString = className[j].innerText;
IdStore.push(dateString);
}
console.log(IdStore);
var IdStore = IdStore.sort(function(a,b){
// Turn your strings into dates, and then subtract them
// to get a value that is either negative, positive, or zero.
return new Date(b.date) - new Date(a.date);
});
console.log(IdStore);
}
storeid();
I expect it to be sorted from nearest date to farthest away but the sorting function isn't doing anything.
You should not be re-declaring a variable here. Remove the var keyword when you are assigning the sort function to IdStore
IdStore = IdStore.sort(function(a,b){
Related
I'm tring to convert a JSON object value to an integer and calculate.
It shows representativeRow.DTA_VAL well but the value of total shows NaN.
I don't think this works because the other code works well.
datav= Number(representativeRow.DTA_VAL);
this is my code
var rows = resp.Sttsapitbldata[1].row;
if (rows) {
var representativeRow;
for (i = 1; i < 30; i++) {
representativeRow = rows[i];
if(representativeRow.ITM_NM.substring(0,2)=="부산"){
// console.log(representativeRow.ITM_NM);
var sub =representativeRow.ITM_NM.substring(0,3);
var total;
var datav;
console.log(representativeRow.DTA_VAL);
datav= Number(representativeRow.DTA_VAL);
total+=datav;
console.log(total);
}
itemNm2 = representativeRow.ITM_NM;
dataV = representativeRow.DTA_VAL;
//console.log(itemNm2);
//console.log(dataV);
options.data.data.push({locname: itemNm2, listshrs: dataV});
}
korea = webponent.visual.korea.init($(".korea"), style, options);
}
See JSON file code below.
{"Sttsapitbldata":[{"head":[{"list_total_count":88},{"RESULT":{"CODE":"INFO-000","MESSAGE":"정상 처리되었습니다."}}]},{"row":[{"STATBL_ID":"T183673021266818","DTACYCLE_CD":"YY","WRTTIME_IDTFR_ID":"2016","ITM_ID":10001,"ITM_NM":"계","CLS_ID":50033,"CLS_NM":"강간","UI_NM":"명","DTA_VAL":5155,"DTA_SVAL":null},{"STATBL_ID":"T183673021266818","DTACYCLE_CD":"YY","WRTTIME_IDTFR_ID":"2016","ITM_ID":10002,"ITM_NM":"서울","CLS_ID":50033,"CLS_NM":"강간","UI_NM":"명","DTA_VAL":1129,"DTA_SVAL":null},{"STATBL_ID":"T183673021266818","DTACYCLE_CD":"YY","WRTTIME_IDTFR_ID":"2016","ITM_ID":10003,"ITM_NM":"부산","CLS_ID":50033,"CLS_NM":"강간","UI_NM":"명","DTA_VAL":314,"DTA_SVAL":null},
You should initialise total=0. You can't add to a null value on the first iteration. Although looking at it, I suspect you'd be wanting to initialise total outside of the loop
I need to get last value from an array and I keep getting this error when I use slice
TypeError: Cannot find function slice in object Sun Jul 23 2017 00:00:00 GMT+0100 (BST). (line 15, file
If I use length -1 I get NaN.
This is the code I am using it.
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Data");
var range = sheet.getDataRange();
var values = range.getValues();
var today = new Date(Date.now());
today.setHours(0,0,0,0);
Logger.log(today);
var setTotal;
var getToday = values[4].map(Number).indexOf(+today);
Logger.log(getToday);
for (i = 0; i < values.length; i++) {
var getTotal = values[i][getToday];
Logger.log(getTotal.slice(-1)[0]);
}
}
... and this is the table
full table
So I need when it match the current day (today) to retrieve last value from that array (column) which is the Total for that day.
Thank you!
Kind regards,
getTotal is always already a singular value.
Also the way you find your column is brittle due to timezones because you normalize only one date.
If you do it with both dates (which needs to be handled safely unless you want to do index constraints) your column finding approach works.
function getTodaysTotal() {
function toUtcMidnight(date) {
try {return date.setHours(0,0,0,0);}
catch(e) {return;}
}
var values = SpreadsheetApp
.getActiveSpreadsheet()
.getSheetByName("Data")
.getDataRange()
.getValues();
var today = toUtcMidnight(new Date());
var todaysColumn = values[4].map(toUtcMidnight).map(Number).indexOf(+today);
var output = values[values.length - 1][todaysColumn];
return values[values.length - 1][todaysColumn];
}
You can use the method .pop() that returns and removes the last element from an array.
Make a copy of the original array first and use .pop() method and assign it to a new value.
var myArray = myArrayCopy
var lastArrayObject = myArrayCopy.pop()
I'm trying to parse multiple subreddit feeds in a Google Script. I can call this Google Script (redditFeeds()) and it returns the title, link, and date to my spreadsheet. However, I want to sort the posts by date so I can see the most recent posts first. I've tried using sort() on the array in various ways and can't get anything sort by descending date. I've even tried converting the date to a Date object and that didn't fix it.
function redditFeeds() {
var entries_array = [];
var subreddit_array = ['https://www.reddit.com/r/funny/top/.rss','https://www.reddit.com/r/news/top/.rss']
for (var s = 0; s < subreddit_array.length; s++) {
var xml = UrlFetchApp.fetch(subreddit_array[s]).getContentText();
var document = XmlService.parse(xml);
var root = document.getRootElement();
var atom = XmlService.getNamespace('http://www.w3.org/2005/Atom');
var entries = document.getRootElement().getChildren('entry', atom);
for (var i = 0; i < entries.length; i++) {
var title = entries[i].getChild('title', atom).getText();
var title = entries[i].getChild('link', atom).getText();
var link = entries[i].getChild('link', atom).getAttribute('href').getValue();
var date = entries[i].getChild('updated', atom).getValue();
entries_array.push([title, link, date]);
}
}
//return entries_array;
//doesn't work
//entries_array.sort(function(a,b) {
// return a.date - b.date;
//});
//also not working
return entries_array.sort(function(a,b) {
new Date(a.date).getTime() - new Date(b.date).getTime();
});
}
I think you want the below, assuming entries_array looks like I think it does. I have no idea what start was supposed to be in your code... I think each entry in entries_array is an array with three members in it, the third being some sort of representation of a date. If it's one that can be parsed by new Date, then this code should work:
return entries_array.sort(function (a, b) {
return new Date(a[2]) - new Date(b[2]);
});
If that's not right, please share what entries_array looks like.
I see a return missing, in the inner sort function and you should not need the getTime()
return entries_array.sort(function(a,b) {
return new Date(a.start) - new Date(b.start);
});
An easy way of sorting date objects is by converting them into UNIX time stamps using dateObj.getTime(). This creates an integer of the seconds since midnight on New Years day 1970. It's very useful if you are working in multiple time zones.
I'm having trouble organizing this data the way I would like it to. On my pages, a few things happen that I know work...
Some PHP spits out a multidimensional associative array. The top level of this array is an array of regions. Each region is an array of timezones.
Some more PHP creates a second multidimensional associative array. The top level of this array is an array of regions. Each region is an array of UTC offsets.
Both arrays are generated in the same order from the same data. This means that $offsets["region"][0] will have be based on the same timezone as $timezones["region"][0].
Both arrays are encoded into JSON and passed to my JavaScript.
I have the following JavaScript code...
var tempCurrentTimezoneArray = timezoneArray[ $("select[name='region_selector']").val() ];
var tempCurrentOffsetArray = timezoneOffsetArray[ $("select[name='region_selector']").val() ];
var groupedTimezones = {};
var groupedOffsets = {};
for (counter = 0; counter < tempCurrentOffsetArray.length; counter++) {
significantOffset = tempCurrentOffsetArray[counter].substr(tempCurrentOffsetArray[counter].length - 2);
if (!(significantOffset in groupedTimezones)) {
groupedTimezones[significantOffset] = [];
groupedOffsets[significantOffset] = [];
}
groupedTimezones[significantOffset].push(tempCurrentTimezoneArray[counter]);
groupedOffsets[significantOffset].push(tempCurrentOffsetArray[counter]);
}
var offsetArray = [];
for (var property in groupedTimezones) {
if (!groupedTimezones.hasOwnProperty(property)) {
continue;
}
groupedTimezones[property].sort();
groupedOffsets[property].sort();
offsetArray.push(parseInt(property));
}
offsetArray.sort();
var currentTimezoneArray = [];
var currentOffsetArray = [];
for (counter = 0; counter < offsetArray.length; counter++) {
currentTimezoneArray = currentTimezoneArray.concat(groupedTimezones[offsetArray[counter]]);
currentOffsetArray = currentOffsetArray.concat(groupedOffsets[offsetArray[counter]]);
}
In the top two lines I remove all of the timezone data not pertaining to the region selected on the page. This means that I am left with 2 single-dimensional arrays. Any given index of either array relates directly to the other array. I.E....
tempCurrentOffsetArray[0] is the UTC offset of the timezone found at tempCurrentTimezoneArray[0].
The rest of this code is intended to complete the following tasks...
Group timezones and offsets by their UTC offset.
Organize each offset group in alphabetical order.
Create two arrays where values are organized first by UTC offset and second by alphabetical order.
The problem I'm having is that on some regions I receive almost perfect listings,and on others I receive some listings with a seemingly random number of undefined values, and I'm not sure why. Can anyone identify the syntactical or logical errors in my code?
JSON of tempCurrentTimezoneArray input data here
JSON of tempCurrentOffsetArray input data here
You think still too complicated. It is a mess to keep these two Arrays in sync, better use one Array with objects.
var region_selector = $("select[name='region_selector']").val();
var tempCurrentTimezoneArray = timezoneArray[ region_selector ];
var tempCurrentOffsetArray = timezoneOffsetArray[ region_selector ];
//consolidate the Arrays
var data = []; //create a new Array `data`
for(var i = tempCurrentOffsetArray.length; i--; ){
//write into Array `data` at index `i` an object, containing these properties:
//`timezone`, `offset` and `offsetValue`, and their respective values
data[i] = {
timezone: tempCurrentTimezoneArray[i],
offset: tempCurrentOffsetArray[i],
//the + at the beginning converts the value behind that into a Number, like parseFloat() would do
offsetValue: +tempCurrentOffsetArray[i].match(/^GMT([+-]\d+(?:\.\d+)?)$/)[1]
}
}
//sorter-function for data to sort the values by offsetValue ASC first, then by timezone ASC
function sortedByOffset(a, b){
return a.offsetValue - b.offsetValue || a.timezone.localeCompare(b.timezone);
}
//you should do this as late as possible, usually after the filtering
data.sort(sortedByOffset);
If you insist on the two output-Arrays
var currentTimezoneArray = data.map(d => d.timezone);
var currentOffsetArray = data.map(d => d.offset);
otherwise this is imo more flexible
//utilities to fetch a property off the object
var getTimezone = d => d.timezone;
//aka function getTimezone(d){ return d.timezone }
var getOffset = d => d.offset;
//aka function getOffset(d){ return d.offset }
//example usages:
data.filter(d => d.offset === "GMT-5").map( getTimezone );
data.filter(d => d.offsetValue >= -2 && d.offsetValue <= -5 ).map( getOffset );
taking the first example; thinking in terms of a SQL-statement this would be
SELECT timezone FROM data WHERE offset = "GMT-5"
get me the timezone-values for each entry where the offset is GMT-5
you start with an Array containsing all values data then you get the subset you are interested in (in this case every entry, with the offset "GMT-5") by filtering.
Now you have an Array containing all values you are intersted in, but still the whole objects; like a SELECT * FROM ...
the map() function calls the function getTimezone() on every entry in this subset and returns another Array containing only the timezone-values.
The second example defines a range for the filter (every entry from GMT-2 to and including GMT-5 and every GMT in between) and returns for these entries the offset-protperty.
I discovered the issue with my code. There were actually three issues the first being on line 6. After looking over the data one more time I realized that some of the values had offsets that were floating point integers or had more than two significant digits. The new line 6 is...
significantOffset = tempCurrentOffsetArray[counter].replace(/[^\d.-]/g, '');
The second issue with my code also had to do with parsing floating integers. On line 21 we need to use parseFloat instead of parseInt. The new line 21 is...
offsetArray.push(parseFloat(property));
The third issue lies on line 23. sort() needs to be told how to sort the integers. This is the new line 23...
offsetArray.sort(function(a, b){return a-b});
The final code looks like this...
var tempCurrentTimezoneArray = timezoneArray[ $("select[name='region_selector']").val() ];
var tempCurrentOffsetArray = timezoneOffsetArray[ $("select[name='region_selector']").val() ];
var groupedTimezones = {};
var groupedOffsets = {};
for (counter = 0; counter < tempCurrentOffsetArray.length; counter++) {
significantOffset = tempCurrentOffsetArray[counter].replace(/[^\d.-]/g, '');
if (!(significantOffset in groupedTimezones)) {
groupedTimezones[significantOffset] = [];
groupedOffsets[significantOffset] = [];
}
groupedTimezones[significantOffset].push(tempCurrentTimezoneArray[counter]);
groupedOffsets[significantOffset].push(tempCurrentOffsetArray[counter]);
}
var offsetArray = [];
for (var property in groupedTimezones) {
if (!groupedTimezones.hasOwnProperty(property)) {
continue;
}
groupedTimezones[property].sort();
groupedOffsets[property].sort();
offsetArray.push(parseFloat(property));
}
offsetArray.sort(function(a, b){return a-b});
var currentTimezoneArray = [];
var currentOffsetArray = [];
for (counter = 0; counter < offsetArray.length; counter++) {
currentTimezoneArray = currentTimezoneArray.concat(groupedTimezones[offsetArray[counter]]);
currentOffsetArray = currentOffsetArray.concat(groupedOffsets[offsetArray[counter]]);
}
I have an array that has following values
Nata_sha_AD8_02_ABA
Jack_DD2_03_K
Alex_AD8_01_PO
Mary_CD3_03_DC
John_DD2_01_ER
Daniel_AD8_04_WS
I want to group them based on following array ['AD8','CD3','DD2','PD0']; and sort each group based on number of each value. So the output should be
Alex_AD8_01_PO
Nata_sha_AD8_02_ABA
Daniel_AD8_04_WS
Mary_CD3_03_DC
John_DD2_01_ER
Jack_DD2_03_K
So far, I wrote following code, but it does not work properly, and I am stuck here.
var temparr = [];
var order = 1000;
var pos = -1;
var temp = -1;
var filterArray= ['AD8','CD3','DD2','PD0'];
for (i =0; i< filterArray.length; i++) {
for (j =0; j < myarray.length; j++) {
if(filterArray[i].toUpperCase().search(myarray[j])>0){
temp = str.substring(myarray[j].indexOf(filterArray[i])+4, myarray[j].indexOf(filterArray[i]+6);
if(temp < order){
pos = j;
order = temp;
}
if(j == myarray.length-1){ //reached end of the loop
temparr.push(myarray[pos]);
order = 1000;
}
}
}
}
Using the first sort parameter you can pass a function to run to sort the array. This function receives 2 values of the array, and should compare them and return less than 0 if the first is lower than the second, higher than 0 if it is higher, or 0 if they are the same. In my proposition, I split the name and "token" part of the values, and then compare the tokens to order them correctly. Using the indexOf on the filterArray allows me to compare the position of the tags accordingly.
var array_to_sort = ['Natasha_AD8_02',
'Jack_DD2_03',
'Alex_AD8_01',
'Mary_CD3_03',
'John_DD2_01',
'Daniel_AD8_04'
];
var filterArray = ['AD8', 'CD3', 'DD2', 'PD0'];
array_to_sort.sort(function(a, b) {
a_token = a.substr(a.indexOf('_')+1); //Remove the name part as it is useless
b_token = b.substr(b.indexOf('_')+1);//Remove the name part as it is useless
if(a_token.substr(0,3) == b_token.substr(0,3)){//If the code is the same, order by the following numbers
if(a_token > b_token){return 1;}
if(a_token < b_token){return -1;}
return 0;
}else{ //Compare the position in the filterArray of each code.
if(filterArray.indexOf(a_token.substr(0,3)) > filterArray.indexOf(b_token.substr(0,3))){return 1;}
if(filterArray.indexOf(a_token.substr(0,3)) < filterArray.indexOf(b_token.substr(0,3))){return -1;}
return 0;
}
});
document.write(array_to_sort);
EDIT: This method will sort in a way that the filterArray can be in any order, and dictates the order wanted. After updates from OP this may not be the requirement... EDIT2: the question being modified more and more, this solution will not work.
My solution.
The only restriction this solution has has is that your sort array has to be sorted already. The XXn_nn part can be anywhere in the string, but it assumes the nn part always follows the XXn part (like DD3_17).
var result=new Array();
var p,x;
//loop the 'search' array
for(var si=0,sl=sort.length;si<sl;si++){
//create new tmp array
var tmp=new Array();
//loop the data array
for(var ai=0,al=arr.length;ai<al;ai++){
var el=arr[ai];
//test if element still exists
if(typeof el=='undefined' || el=='')continue;
//test if element has 'XXn_nn' part
if(arr[ai].indexOf(sort[si]) > -1){
//we don't now where the 'XXn_nn' part is, so we split on '_' and look for it
x=el.split('_');
p=x.indexOf(sort[si]);
//add element to tmp array on position nn
tmp[parseInt(x[p+1])]=el;
//remove element from ariginal array, making sure we don't check it again
arr.splice(ai,1);ai--;
}
}
//remove empty's from tmp array
tmp=tmp.filter(function(n){return n!=undefined});
//add to result array
result=result.concat(tmp);
}
And a working fiddle
On the basis that the filtering array is in alphabetical order, and that every string has a substring in the format _XXN_NN_ that you actually want to sort on, it should be sufficient simply to sort based on extracting that substring, without reference to filterArray:
var names = ['Nata_sha_AD8_02_ABA', 'Jack_DD2_03_K', 'Alex_AD8_01_PO', 'Mary_CD3_03_DC', 'John_DD2_01_ER', 'Daniel_AD8_04_WS'];
names.sort(function(a, b) {
var re = /_((AD8|CD3|DD2|PD0)_\d\d)_/;
a = a.match(re)[1];
b = b.match(re)[1];
return a.localeCompare(b);
});
alert(names);