JavaScript loop through to check duplicate value - javascript

I am having troubles trying to check if the date exists in the array.
for(var i = 0; i< crisislist.length; i++){
hazecounter = 1;
if(crisislist[i].category == 1){
if(crisislist[i].date != crisislist[i+1].date) {
hazelabel.push(crisislist[i].date);
}else{
hazecounter++;
}
hazedata.push(hazecounter);
}
}
The sample data for the date is:
["01-02-2017", "22-03-2017", "22-03-2017", "07-08-2017"]
And the expected output for hazelabel, hazedata should be:
hazelabel: ["01-02-2017", "22-03-2017", "07-08-2017"]
hazedata: [1,2,1]
With the code above, when I check until the last element in the array and trying to make a comparison, it throw me an error message:
Uncaught TypeError: Cannot read property 'date' of undefined
I think this is because when I reach the last element of array, and I try to find crisislist[I+1].date, it could not found and thus the error message.
Any idea how to fix this? Thanks in advance!

You must access crisislist[i+1].date only when i doesn't point to the last element.
Also notice that to get the desired result, you need to move the hazedata.push inside the if block and put the initialisation of hazecounter in front of the loop.
var hazecounter = 1;
for (var i = 0; i< crisislist.length; i++) {
if (crisislist[i].category == 1) {
if (i == crisislist.length-1 || crisislist[i].date != crisislist[i+1].date) {
hazelabel.push(crisislist[i].date);
hazedata.push(hazecounter);
hazeCounter = 1;
} else {
hazecounter++;
}
}
}

Your if statement is going to be a problem.
if(crisislist[i].date != crisislist[i+1].date) {
You are accessing crisislist[i+1] in a loop that goes to < crisislist.length. That means that if you have an array of size 4, your loop will go until i = 3, but you are accessing i+1 from the array (crisislist[4]), which will be undefined.
Try changing your for loop to go to crisis.length-1

You just need to check till second last :
for(var i = 0; i< (crisislist.length-1); i++){
hazecounter = 1;
if(crisislist[i].category == 1){
if(crisislist[i].date != crisislist[i+1].date) {
hazelabel.push(crisislist[i].date);
if (crisislist.length-2 == i)
{
hazelabel.push(crisislist[i+1].date);
}
}else{
hazecounter++;
}
hazedata.push(hazecounter);
}
}

Check that code. If you have any questions, add a comment :) In my solution dates dont have to be sorted.
</head>
<BODY>
<script>
function Something(date)
{
this.date = date;
this.category = 1;
}
var crisislist = [];
var hazelabel = [];
var hazedata = [];
crisislist[0] = new Something("01-02-2017");
crisislist[1] = new Something("22-03-2017");
crisislist[2] = new Something("22-03-2017");
crisislist[3] = new Something("07-08-2017");
for(var i = 0; i< crisislist.length; i++){
if(crisislist[i].category == 1)
{
if(!hazelabel[crisislist[i].date])
{
hazelabel[crisislist[i].date] = crisislist[i].date;
hazedata[crisislist[i].date] = 1;
}
else
{
hazedata[crisislist[i].date]++;
}
}
}
for(var key in hazelabel)
{
console.log(hazelabel[key]);
console.log(hazedata[key]);
}
</script>
</BODY>
</HTML>

Related

Cant get my foor loop working

Why isn't this working?
var i = 0;
for (i < 1) {
if ($(".button[name=commit]").val() == "remove"){
i = 1;
}
}
I get this error message saying: unexpcted token ) at line 2.
Here you go with a solution using while loop
var i = 0;
while (i < 1) {
if ($(".button[name=commit]").val() == "remove"){
i = 1;
}
}
Here you go with a solution using for loop
for (var i=0; i<1;) {
if ($(".button[name=commit]").val() == "remove"){
i = 1;
}
}
Hope this will help you.
while(!$(".button[name=commit]").val() == "remove");
it was not working since for() needs 3 commands: Initialization, guard and last action: for(init;guard;action)

If for loop returns null javascript

I have a loop with inner if statements as follows
var html = "";
var i;
for (i = 0; i < products.length; i++)
{
if(products[i].attrs.product_type == type)
{
html += '<p>hello world</p>';
}
}
I'd really like to be able to say if no results are returned from for loop, say "Sorry, no results were found" etc… I've tried the following… 
for (i = 0; i < products.length; i++)
{
if(products[i].attrs.product_type == type)
{
html += '<p>hello world</p>' +i;
}
}
But that just puts the object number next to the returned result…
Any help would be great as I'm sure this is very easy
Thanks
At the end check whether the html variable is actually filled, if not we didn't find any items and we can use the sorry message:
var html = '';
var i;
for (i = 0; i < products.length; i++)
{
if(products[i].attrs.product_type === type)
{
html += '<p>hello world</p>';
}
}
if (html === '') { // or: "if (!html)" if you like that sort of thing
html = 'Sorry, no results were found'
}
Also notice that I changed the comparison from == to ===. That's because == tries to convert the type. While === does not. Use === to prevent strange errors, usually that's the one you want. For more info on it: Which equals operator (== vs ===) should be used in JavaScript comparisons?
Updated because of comment by #ASDFGerte
Similar to shotor's answer, but a slightly different approach would be as follows:
var html = "";
var i;
var found = false;
for (i = 0; i < products.length; i++)
{
if(products[i].attrs.product_type === type)
{
html += '<p>hello world</p>' +i;
found = true;
}
}
if (found === false)
{
//do stuff here.
}
var html = "";
var i;
var hasResult = false;
for ( i = 0; i < products.length; i++ )
{
if( products[i].attrs.product_type == type )
{
html += '<p>hello world</p>';
hasResult = true;
}
}
if( !hasResult ){
html = "No match";
}

Undefined property in array of arrays

I am working on an array of array, and I want to test each first value but all what I get is Uncaught TypeError: Cannot read property '0' of undefined.
Help please!
function getManualDesactivation(data){
var tab=[];
var l=data.length ;
var listeService= getCategorie(data);
var resultat=[];
for(var i=0; i<l;i++){
if (data[i][1] == "DESACTIVATION") {
var subtab=[];
subtab.push(data[i][0]);
subtab.push(data[i][2]);
tab.push(subtab);
}
}
if (tab.length > 1) {
var j = 0;
for (var i = 0; i < listeService.length; i++) {
if (listeService[i] == tab[j][0]) {<---- here is the exception
resultat.push(tab[j][1]);
j++;
} else {
resultat.push(0);
j++;
}
}
}
That error is caused by trying to access the 0 index of variable that does not exist.
To ensure that you are checking the index of a defined value, you can write:
if (tab[j] && listeService[i] == tab[j][0]) {
resultat.push(tab[j][1]);
j++;
} else {
resultat.push(0);
j++;
}

Does not execute the code after a for within a function

Good! I have a problem and you do not run my code at the end of the loop, the above and what is inside the loop works fine, the problem is that after the loop is still not executing the code. Any idea why it can be?
This is my code:
var arrayp = new Array();
function botonAdelante(tabl, pasos)
{
var padreTabla = document.getElementById(tabl).rows;
var cont = 0;
for(var j = 0; j < padreTabla.length; j++)
{
var hijoTd = document.getElementById(pasos+ "-producto-" +j);
var childArray = hijoTd.children;
for(var i = 0; i < childArray.length; i++)
{
var check = document.getElementById(pasos+ "-CheckBox-" +j);
if(check.type == 'checkbox' && check.checked==true)
{
arrayp[cont] = check.value;
var algo = arrayp[cont];
alert(arrayp[cont]);
alert(arrayp);
cont++;
continue;
};
}
}
alert("It is in this part of the code does not work");
}
Clarification: "continue" found at the end of long and if it will not work either.
The continue is confusing used like this, but I have a feeling your code is probably throwing an error because the cont might exceed the array length. Regardless of whether this fixes it or not I'd at least add a check to ensure that it doesn't throw an exception.
Please check for exceptions being thrown through web dev tools (F12 in Chrome).
for(var i = 0; i < childArray.length; i++)
{
var check = document.getElementById(pasos+ "-CheckBox-" +j);
if(check.type == 'checkbox' && check.checked==true && arrayp.length <= cont)
{
arrayp[cont] = check.value;
var algo = arrayp[cont];
alert(arrayp[cont]);
alert(arrayp);
cont++;
continue;
};
}

two delimiters output formatting javascript

I thought this would be easier, but running into a weird issue.
I want to split the following:
theList = 'firstword:subwordone;subwordtwo;subwordthree;secondword:subwordone;thirdword:subwordone;subwordtwo;';
and have the output be
firstword
subwordone
subwordtwo
subwordthree
secondword
subwordone
thirdword
subwordone
subwordtwo
The caveat is sometimes the list can be
theList = 'subwordone;subwordtwo;subwordthree;subwordfour;'
ie no ':' substrings to print out, and that would look like just
subwordone
subwordtwo
subwordthree
subwordfour
I have tried variations of the following base function, trying recursion, but either get into infinite loops, or undefined output.
function getUl(theList, splitOn){
var r = '<ul>';
var items = theList.split(splitOn);
for(var li in items){
r += ('<li>'+items[li]+'</li>');
}
r += '</ul>';
return r;
}
The above function is just my starting point and obviously doesnt work, just wanted to show what path I am going down, and to be shown the correct path, if this is totally off base.
It seems you need two cases, and the difference between the two is whether there is a : in your string.
if(theList.indexOf(':') == -1){
//Handle the no sublist case
} else {
//Handle the sublist case
}
Starting with the no sublist case, we develop the simple pattern:
var elements = theList.split(';');
for(var i = 0; i < elements.length; i++){
var element = elements[i];
//Add your element to your list
}
Finally, we apply that same pattern to come up with the implementation for the sublist case:
var elements = theList.split(';');
for(var i = 0; i < elements.length; i++){
var element = elements[i];
if(element.indexOf(':') == -1){
//Add your simple element to your list
} else {
var innerElements = element.split(':');
//Add innerElements[0] as your parent element
//Add innerElements[1] as your child element
//Increment i until you hit another element with ':', adding the single elements each increment as child elements.
//Decrement i so it considers the element with the ':' as a parent element.
}
}
Keep track of the current list to add items to, and create a new list when you find a colon in an item:
var baseParent = $('ul'), parent = baseParent;
$.each(theList.split(';'), function(i, e) {
if (e.length) {
var p = e.split(':');
if (p.length > 1) {
baseParent.append($('<li>').append($('<span>').text(p[0])).append(parent = $('<ul>')));
}
parent.append($('<li>').text(p[p.length - 1]));
}
});
Demo: http://jsfiddle.net/Guffa/eWQpR/
Demo for "1;2;3;4;": http://jsfiddle.net/Guffa/eWQpR/2/
There's probably a more elegant solution but this does the trick. (See edit below)
function showLists(text) {
// Build the lists
var lists = {'': []};
for(var i = 0, listKey = ''; i < text.length; i += 2) {
if(text[i + 1] == ':') {
listKey = text[i];
lists[listKey] = [];
} else {
lists[listKey].push(text[i]);
}
}
// Show the lists
for(var listName in lists) {
if(listName) console.log(listName);
for(var j in lists[listName]) {
console.log((listName ? ' ' : '') + lists[listName][j]);
}
}
}
EDIT
Another interesting approach you could take would be to start by breaking it up into sections (assuming text equals one of the examples you gave):
var lists = text.match(/([\w]:)?([\w];)+/g);
Then you have broken down the problem into simpler segments
for(var i = 0; i < lists.length; i++) {
var listParts = lists[i].split(':');
if(listParts.length == 1) {
console.log(listParts[0].split(';').join("\n"));
} else {
console.log(listParts[0]);
console.log(' ' + listParts[1].split(';').join("\n "));
}
}
The following snippet displays the list depending on your requirements
var str = 'subwordone;subwordtwo;subwordthree;';
var a = []; var arr = [];
a = str;
var final = [];
function split_string(a){
var no_colon = true;
for(var i = 0; i < a.length; i++){
if(a[i] == ':'){
no_colon = false;
var temp;
var index = a[i-1];
var rest = a.substring(i+1);
final[index] = split_string(rest);
return a.substring(0, i-2);
}
}
if(no_colon) return a;
}
function display_list(element, index, array) {
$('#results ul').append('<li>'+element+'</li>');
}
var no_colon_string = split_string(a).split(';');
if(no_colon_string){
$('#results').append('<ul><ul>');
}
no_colon_string.forEach(display_list);
console.log(final);
working fiddle here

Categories