I'm having issues to get the stored data in my array. I can't see where is the problem on my function and why is returning undefined elements.
This is the function where I store data in the array:
function getTaskKidData(str) {
var tasks = $('#tasks_data > div');;
var formated_tasks = [];
var formated_kids = [];
formated_homeworks = [];
tasks.each(function(index) {
var task_kids = $(this).find('ul').eq(0).find('li');
var task_homeworks = $(this).find('ul').eq(1).find('li');
if (task_kids.length > 0 && task_homeworks.length > 0) {
task_kids.each(function(index) {
var kid_name = $(this).text().trim();
if (str == "kid"){
var kid = $('#kid_list > li > a[class*="active"]').text().replace(window.location.pathname.split('/')[2],'').trim();
if (kid == kid_name){
formated_kids.push({'name': kid_name});
}
}else{
formated_kids.push({'name': kid_name});
}
});
task_homeworks.each(function(index) {
var homework_name = $(this).find('p').eq(0).text().trim();
var homework_date = $(this).find('p').eq(1).text().trim();
formated_homeworks.push({
'name': homework_name,
'date': homework_date,
});
});
formated_tasks.push({
'kids': task_kids,
'homeworks': task_homeworks,
})
}
});
return formated_tasks;
}
I don't understand why the objects in the output of the array are "li" tags if I'm storing data as text. The output of the array is the next one:
This is the code where I'm trying to get the data:
var tasks = getTaskKidData("kid");
console.log(tasks)
for (let i = 0; i < tasks.length; i++) {
console.log("schedule");
for (let j = 0; j < tasks[i]['kids'].length; j++) {
console.log(tasks[i]['kids'][j]['name']);
}
for (let j = 0; j < tasks[i]['homeworks'].length; j++) {
console.log(tasks[i]['homeworks'][j]['name']);
console.log(tasks[i]['homeworks'][j]['date']);
}
}
And this is the output when I run the code:
Any idea of the problem?
Thanks for reading!!
In your code you have
var task_kids = $(this).find('ul').eq(0).find('li');
and later you log task_kids. The log output shows li elements because that was what you selected.
Related
I'm trying to filter in an array by data in another array using concat in a for loop. The elements of the following code are logging correctly, but the final array is logging an empty array.
function Shipments (){
var app = SpreadsheetApp;
var movementSS = app.getActiveSpreadsheet();
var infoSheet = movementSS.getSheetByName("Update Info");
var orderInfoSheet = movementSS.getSheetByName("Order Info");
var targetSheet = movementSS.getSheetByName("Shipments");
var ShipLogSS = app.openByUrl(URL).getSheetByName("Shipping Details");
var ShipArr = ShipLogSS.getRange(3,1,ShipLogSS.getLastRow(),ShipLogSS.getLastColumn()).getValues().
filter(function(item){if(item[1]!=""){return true}}).
map(function(r){return [r[0],r[1],r[2],r[4],r[10],r[11],r[16],r[18],r[23]]});
var supplierData = orderInfoSheet.getRange(3,6,orderInfoSheet.getLastRow(),1).getValues().
filter(function(item){if(item[0]!=""){return true}});
var supplierList = [];
for (var i in supplierData) {
var row = supplierData[i];
var duplicate = false;
for (var j in supplierList) {
if (row.join() == supplierList[j].join()) {
duplicate = true;
}
}
if (!duplicate) {
supplierList.push(row);
}
}
var supplierFilter = [];
for(var i = 0; i < supplierList.length; i++){
var shipments = ShipArr.filter(function(item){if(item[4]===supplierList[i][0]){return true}});
supplierFilter.concat(shipments);
}
Logger.log(supplierFilter);
}
Any help would be greatly appreciated!
You need to assign the result of concat onto the supplierFilter in order to see the changes in later iterations and in the outer scope.
You can also return the comparison done inside the .filter callback immediately, instead of an if statement - it looks a bit cleaner.
var supplierFilter = [];
for (var i = 0; i < supplierList.length; i++) {
var shipments = ShipArr.filter(function (item) { return item[4] === supplierList[i][0]; });
supplierFilter = supplierFilter.concat(shipments);
}
Logger.log(supplierFilter);
I'm currently developing a sheet that shows results from a set of data based on some filters but the data loads to slowly when getting the results, I've tried to follow the Best Practices from Google Documentacion with no luck, how can I set an array for the data to load faster?
Below is the code commented with what I've already tried
function realizarBusqueda() {
var inicio = SpreadsheetApp.getActive().getSheetByName("INICIO");
var aux_tags = SpreadsheetApp.getActive().getSheetByName("Aux_Tags");
var data = SpreadsheetApp.getActive().getSheetByName("Data");
var data_lc = data.getLastColumn();
var data_lr = data.getLastRow();
var searchRange = data.getRange(2,1, data_lr, data_lc);
var inicio_lc = inicio.getLastColumn();
inicio.getRange("A8:L1000").clearContent();
inicio.getRange("A8:L1000").clearFormat();
var countRows = inicio.getMaxRows();
inicio.deleteRows(20, (20-countRows)*-1);
if (inicio.getRange("B4").isBlank()) {
inicio.getRange("A8:L1000").clearContent();
inicio.getRange("A8:L1000").clearFormat();
var countRows = inicio.getMaxRows();
inicio.deleteRows(20, (20-countRows)*-1);
SpreadsheetApp.flush();
}
else if ((inicio.getRange("B4").getValue() != "" &&
inicio.getRange("C4").getValue() === "")) {
//filtrado 1
var arrayDatos = searchRange.getValues();
var inicio_fr = 8;
//var row = new Array(11);
for (var j = 2; j <= data_lr; j++) {
//row[j] = new Array(data_lr);
if (aux_tags.getRange("P2").getValue() === arrayDatos[j-2][4]) {
var inicio_fc = 1;
for (var i = 0; i < arrayDatos[j-2].length; i++) {
//row[j][i] = arrayDatos[j-2][i];
var row = arrayDatos[j-2][i];
inicio.getRange(inicio_fr, inicio_fc).setValue(row);
inicio_fc++;
}
inicio_fr++;
}
//inicio.getRange("A8").setValues(row);
}
}
I expect the output to load lots faster, currently what I've tried is commented, the code as-is is working but too slow
I just wanted to update this subject because I figured out myself, see attached the new code with the use of new 2D arrays
...
//filtrado 1
var arrayDatos = searchRange.getValues();
var inicio_fr = 8;
var rows = [];
var row = [];
for (var j = 2; j <= data_lr; j++) {
if (aux_tags.getRange("P2").getValue() === arrayDatos[j-2][4]) {
var inicio_fc = 1;
for (var i = 0; i < arrayDatos[j-2].length; i++) {
row.push(arrayDatos[j-2][i]);
if (i == 11) {
rows.push(row);
row = [];
}
}
}
}
inicio.getRange(8, 1, rows.length, rows[0].length).setValues(rows);
}
Now instead of writing on row at a time, I just write the whole array at once
I am trying to add values in a multidimensional array in JavaScript, but it doesn't seem to work. I get "variable not defined" error in snippet but can't see any variable which is not defined.
Does anyone have any idea what's going wrong here?
Many Thanks,
Hassam
var abc = "11:00, 11:10, 12:20,12:30";
var split = abc.split(",")
var limits = new Array();
var alltimes = [[],[]];
//var split = ["11:00", "11:10", "12:20","12:30"];
var x = 0;
for (var i = 0; i < split.length -1 ; i++) {
limits.push(split[i]);
// alert(split.length );
if(i%2 === 1) // If odd value
{
alert(limits);
for (var j = 0;j<2; j++)
{
// alert(limits[j]);
alltimes[x][j] = limits[j];
}
limits.length = 0;
x++;
}
// alert(split.length + 2);
//
}
alert(alltimes);
// console.log(abc)
This is my JavaScript code
$(document).ready(function(){
$('.timepicker').click(function(){
var ajaxurl = 'Ajax.php',
data = {'action': 'Hassam'};
$.post(ajaxurl, data, function (response) {
// $('#timepicker').timepicker('option', 'disableTimeRanges', [abc]);
var split = response.split(",");
var x = 0;
for (var i = 0; i < split.length -1 ; i++) {
limits.push(split[i]);
alert(split.length );
if(i%2 === 1) // If odd value
{
for (var j = 0;j<2; j++)
{
// alert(limits[j]);
alltimes[x][j] = limits[j];
}
limits.length = 0;
x++;
}
alert(split.length + 2);
//
}
alert(alltimes);
// console.log(abc)
});
There is very simple solution to achieve what you want.
var split = ["11:00", "11:10", "12:20", "12:30"];
var alltimes = [];
while (split.length) {
alltimes.push(split.splice(0, 2));
}
console.log(alltimes);
I'm writing a program in JS for checking equal angles in GeoGebra.
This is my first JS code, I used c# formerly for game programming.
The code is:
var names = ggbApplet.getAllObjectNames();
var lines = new Set();
var angles = new Set();
var groups = new Set();
for(var i=0; i<names.length; i++)
{
if(getObjectType(names[i].e)==="line")
{
lines.add(names[i]);
}
}
for(var i=0;i<lines.size;i++)
{
for(var j=0;j<i;j++)
{
var angle = new Angle(i,j);
angles.add(angle);
}
}
for(var i=0;i<angles.size;i++)
{
var thisVal = angles.get(i).value;
var placed = false;
for(var j=0;j<groups.size;j++)
{
if(groups.get(j).get(0).value===thisVal)
{
groups.get(j).add(angles.get(i));
placed = true;
}
}
if(!placed)
{
var newGroup = new Set();
newGroup.add(angles.get(i));
groups.add(newGroup);
}
}
for(var i=0;i<groups.size;i++)
{
var list="";
for(var j=0;j<groups.get(i).size;j++)
{
list = list+groups.get(i).get(j).name;
if(j != groups.get(i).size-1)
{
list = list+",";
}
}
var comm1 = "Checkbox[angle_{"+groups.get(i).get(0).value+"},{"+list+"}]";
ggbApplet.evalCommand(comm1);
var comm2 = "SetValue[angle_{"+groups.get(i).get(0).value+"}+,0]";
ggbApplet.evalCommand(comm2);
}
(function Angle (i, j)
{
this.lineA = lines.get(i);
this.lineB = lines.get(j);
this.name = "angleA_"+i+"B_"+j;
var comm3 = "angleA_"+i+"B_"+j+" = Angle["+this.lineA+","+this.lineB+"]";
ggbApplet.evalCommand(comm3);
var val = ggbApplet.getValue(this.name);
if(val>180)
{val = val-180}
this.value = val;
ggbApplet.setVisible(name,false)
});
function Set {
var elm;
this.elements=elm;
this.size=0;
}
Set.prototype.get = new function(index)
{
return this.elements[index];
}
Set.prototype.add = new function(object)
{
this.elements[this.size]=object;
this.size = this.size+1;
}
It turned out that GeoGebra does not recognize Sets so I tried to make a Set function.
Basically it collects all lines into a set, calculates the angles between them, groups them and makes checkboxes to trigger visuals.
the GeoGebra functions can be called via ggbApplet and the original Workspace commands via ggbApplet.evalCommand(String) and the Workspace commands I used are the basic Checkbox, SetValue and Angle commands.
The syntax for GeoGebra commands are:
Checkbox[ <Caption>, <List> ]
SetValue[ <Boolean|Checkbox>, <0|1> ]
Angle[ <Line>, <Line> ]
Thank you for your help!
In short, the syntax error you're running to is because of these lines of code:
function Set {
and after fixing this, new function(index) / new function(object) will also cause problems.
This isn't valid JS, you're likely looking for this:
function Set() {
this.elements = [];
this.size = 0;
}
Set.prototype.get = function(index) {
return this.elements[index];
};
Set.prototype.add = function(object) {
this.elements[this.size] = object;
this.size = this.size + 1;
};
Notice no new before each function as well.
I'm not sure what you're trying to accomplish by creating this Set object though - it looks like a wrapper for holding an array and its size, similar to how something might be implemented in C. In JavaScript, arrays can be mutated freely without worrying about memory.
Here's an untested refactor that removes the use of Set in favour of native JavaScript capabilities (mostly mutable arrays):
var names = ggbApplet.getAllObjectNames();
var lines = [];
var angles = [];
var groups = [];
for (var i = 0; i < names.length; i++) {
if (getObjectType(names[i].e) === "line") {
lines.push(names[i]);
}
}
for (var i = 0; i < lines.length; i++) {
for (var j = 0; j < i; j++) {
angles.push(new Angle(i, j));
}
}
for (var i = 0; i < angles.length; i++) {
var thisVal = angles[i].value;
var placed = false;
for (var j = 0; j < groups.length; j++) {
if (groups[j][0].value === thisVal) {
groups[j].push(angles[i]);
placed = true;
}
}
if (!placed) {
groups.push([angles[i]]);
}
}
for (var i = 0; i < groups.length; i++) {
var list = "";
for (var j = 0; j < groups[i].length; j++) {
list += groups[i][j].name;
if (j != groups[i].length - 1) {
list += ",";
}
}
var comm1 = "Checkbox[angle_{" + groups[i][0].value + "},{" + list + "}]";
ggbApplet.evalCommand(comm1);
var comm2 = "SetValue[angle_{" + groups[i][0].value + "}+,0]";
ggbApplet.evalCommand(comm2);
}
function Angle(i, j) {
this.name = "angleA_" + i + "B_" + j;
var comm3 = "angleA_" + i + "B_" + j + " = Angle[" + lines[i] + "," + lines[j] + "]";
ggbApplet.evalCommand(comm3);
var val = ggbApplet.getValue(this.name);
if (val > 180) {
val -= 180;
}
this.value = val;
ggbApplet.setVisible(name, false);
}
Hopefully this helps!
Your function definition is missing the parameter list after the function name.
Also, you're initializing the elements property to an undefined value. You need to initialize it to an empty array, so that the add method can set elements of it.
function Set() {
this.elements=[];
this.size=0;
}
I have a javascript object as below
var mydata=[
{"Club":"Blackburn","EventNo":1,"Pnts":3,"CumPnts":0},
{"Club":"Blackburn","EventNo":2,"Pnts":1,"CumPnts":0},
{"Club":"Blackburn","EventNo":3,"Pnts":4,"CumPnts":0},
{"Club":"Preston","EventNo":1,"Pnts":2,"CumPnts":0},
{"Club":"Preston","EventNo":2,"Pnts":4,"CumPnts":0},
{"Club":"Preston","EventNo":3,"Pnts":2,"CumPnts":0},]
I want to update the object so that CumPnts contains a running points total for each Club as below
{"Club":"Blackburn","EventNo":1,"Pnts":3,"CumPnts":3},
{"Club":"Blackburn","EventNo":2,"Pnts":1,"CumPnts":4},
{"Club":"Blackburn","EventNo":3,"Pnts":4,"CumPnts":8},
{"Club":"Preston","EventNo":1,"Pnts":2,"CumPnts":2},
{"Club":"Preston","EventNo":2,"Pnts":4,"CumPnts":6},
{"Club":"Preston","EventNo":3,"Pnts":1,"CumPnts":7},]
Any help would be much appreciated
Here is a function that loops through the list and updates it after it's been added. But I suspect that the events come in one at a time so there could be another function that can look the cumPtns obj and take from that. Here is for the current list.
var cumData = {};
var mydata=[
{"Club":"Blackburn","EventNo":1,"Pnts":3,"CumPnts":0},
{"Club":"Blackburn","EventNo":2,"Pnts":1,"CumPnts":0},
{"Club":"Blackburn","EventNo":3,"Pnts":4,"CumPnts":0},
{"Club":"Preston","EventNo":1,"Pnts":2,"CumPnts":0},
{"Club":"Preston","EventNo":2,"Pnts":4,"CumPnts":0},
{"Club":"Preston","EventNo":3,"Pnts":2,"CumPnts":0}];
function updateMyData() {
for (var i = 0; i < mydata.length; i++) {
var item = mydata[i];
if(cumData[item.Club] == undefined) {
cumData[item.Club] = {};
cumData[item.Club] = item.Pnts;
} else {
cumData[item.Club] = cumData[item.Club] + item.Pnts;
}
mydata[i].CumPnts = cumData[item.Club];
};
console.log(mydata);
//if you want to return it you can have this line below. Otherwise the object is updated so you'll probably want to do something with it once it's updated. Call back maybe?
return mydata;
}
updateMyData();
The first time it encounters a team it adds it to an array and so does with the corresponding cumPnts, so we can keep track of whether we checked a team earlier or not.
var tmArr = [];
var cumArr = [];
for(var i = 0; i < mydata.length; i++) {
var elm = mydata[i];
var club = elm.Club;
var points = elm.Pnts;
var idx = tmArr.indexOf(club);
if(idx > -1) {
cumArr[idx] += points;
elm.CumPnts = cumArr[idx];
}
else {
elm.CumPnts = points;
tmArr[tmArr.length] = club;
cumArr[cumArr.length] = points;
}
}
jsfiddle DEMO