Toon posts:

[js]if-else mania.

Pagina: 1
Acties:

Verwijderd

Topicstarter
hallo,

bij een code van mij heb ik een beetje last van if-else mania.
4 dubbele if-else statements met wat for loops ertussen.
hier is het stukje code waar ik het over heb:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if(!r) {
    if(0<x) {
        if(root) {
            for(lo=0;lo<max;lo++) {
                if(parseInt(le)==parseInt(x+lo)) {
                    d("balk"+(lo+1)).innerHTML = "&nbsp;&raquo";
                } else {
                    d("balk"+(lo+1)).innerHTML = parseInt(x+lo);
                }
            }
        } else {
            for(lo=0;lo<(max-2);lo++) {
                d("balk"+(lo+1)).innerHTML = "&nbsp;&raquo";
            }
        }
    } else {
        x=1;
    }
} else {
    startr(rurl[r-1]);
    ping=1;
    r=0;
}
ik ben tegenwoordig wel aan het werken met de verkorte if-else statement (var=(condition)?true:false;)
maar ik heb niet zoveel verstand van de case-switch-break(of hoe dat ding ook heet) en while loops,
maar is het mogelijk om deze code mooier te maken?
natuurlijk moet het wel hetzelfde doen, maar dit is zo lelijk en ik denk dat het korter kan, alleen niet hoe.

kan iemand mij helpen met het verkorten van deze code?

greetz
dexus

  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 08-05 11:43
JavaScript:
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
32
33
34
35
36
37
if(!r) 
{
    if(0<x) 
    {
        if(root) 
        {
            for(lo=0;lo<max;lo++) 
            {
                if(parseInt(le)==parseInt(x+lo)) 
                {
                    d("balk"+(lo+1)).innerHTML = "&nbsp;&raquo";
                }
                else
                {
                    d("balk"+(lo+1)).innerHTML = parseInt(x+lo);
                }
            }
        } 
        else 
        {
            for(lo=0;lo<(max-2);lo++) 
            {
                d("balk"+(lo+1)).innerHTML = "&nbsp;&raquo";
            }
        }
    } 
    else 
    {
        x=1;
    }
} 
else 
{
    startr(rurl[r-1]);
    ping=1;
    r=0;
}


is al aardig beter leesbaar, zo lijn ik ze altijd uit...

edit:

En zo kan ook (mits 't in ee nfunctie staat)

JavaScript:
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
32
33
34
35
if(r) 
{
    startr(rurl[r-1]);
    ping=1;
    r=0;
    return;
}

if(!(0<x)) 
{
    x=1;
    return;
}

if(!root)
{
    for(lo=0;lo<(max-2);lo++) 
    {
        d("balk"+(lo+1)).innerHTML = "&nbsp;&raquo";
    }
    return;
}


for(lo=0;lo<max;lo++) 
{
    if(parseInt(le)==parseInt(x+lo)) 
    {
        d("balk"+(lo+1)).innerHTML = "&nbsp;&raquo";
    }
    else
    {
        d("balk"+(lo+1)).innerHTML = parseInt(x+lo);
    }
}

[ Voor 46% gewijzigd door Mithrandir op 30-03-2005 18:57 ]

Verbouwing


  • dxta
  • Registratie: Maart 2002
  • Niet online

dxta

Moo!

Probeer eens een paar and en or statements te gebruiken. In java is dit && voor and en || voor or, dat scheelt je al een hoop code :)

[ Voor 6% gewijzigd door dxta op 30-03-2005 18:56 ]

Omelette du fromage!


  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 08-05 11:43
Dxta schreef op woensdag 30 maart 2005 @ 18:56:
Probeer eens een paar and en or statements te gebruiken. In java is dit && voor and en || voor or, dat scheelt je al een hoop code :)
Omdat bij iedere status van de variableen er iet sanders uitgevoerd moet worden, is dit geen optie.

Waarom heb je trouwens zulke slechte variabele-namen?

Verbouwing


  • jotheman
  • Registratie: September 2000
  • Laatst online: 04-05 20:19

jotheman

Was like that when I got here!

Idd, probeer eens &&'s, dat scheelt een stuk denk ik. Misschien kun je ook for's of while's gebruiken? Die korten meestal ook 'n flink stuk in... Ik ben er teveel van vergeten om 't zelf bij je stukje code te doen, soz...

I see dead pixels...


  • Gertjan
  • Registratie: Oktober 2001
  • Laatst online: 07-02 20:23

Gertjan

mmmm, beer...

Mithrandir schreef op woensdag 30 maart 2005 @ 18:57:
[...]
Omdat bij iedere status van de variableen er iet sanders uitgevoerd moet worden, is dit geen optie.
Waarom niet? Volgens mij kan het ook zoals hieronder staat:
code:
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
if( (!r) && (x > 0) && root )
{
  for(lo=0;lo<max;lo++)
  {
    if(parseInt(le)==parseInt(x+lo))
    {
      d("balk"+(lo+1)).innerHTML = "&nbsp;&raquo";
    } 
    else
    {
      d("balk"+(lo+1)).innerHTML = parseInt(x+lo);
    }
  }
}
else if( (!r) && (x > 0) ) 
{
  for(lo=0;lo<(max-2);lo++)
  {
    d("balk"+(lo+1)).innerHTML = "&nbsp;&raquo";
  }
}
else if( !r )
{
  x=1;
}
else 
{
    startr(rurl[r-1]);
    ping=1;
    r=0;
}

[ Voor 9% gewijzigd door Gertjan op 30-03-2005 19:02 ]


  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 08-05 11:43
Ali_Illegali schreef op woensdag 30 maart 2005 @ 19:00:
[...]

Waarom niet? Volgens mij kan het ook zoals hieronder staat:
code:
1
[knip]
Wil je zeggen dat op deze manier je code duidelijker wordt? Door zulke statements meer dan 1 keer op te schrijven is het moeilijker achteraf te controleren wat er nu gebeurt met welke input.

Verbouwing


  • Gertjan
  • Registratie: Oktober 2001
  • Laatst online: 07-02 20:23

Gertjan

mmmm, beer...

Mithrandir schreef op woensdag 30 maart 2005 @ 19:03:
Wil je zeggen dat op deze manier je code duidelijker wordt? Door zulke statements meer dan 1 keer op te schrijven is het moeilijker achteraf te controleren wat er nu gebeurt met welke input.
Ik vind dit een heel stuk duidelijker dan statements die 5-diep genest zijn, ja. Wellicht kan er aan de logica van het hele stuk code nog veel verbeterd worden, maar daarvoor is meer informatie nodig van de topicstarter.

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
pin me er niet op vast maar volgens mij staat hier hetzelfde:

code:
1
2
3
4
5
6
7
8
9
10
11
12
if(0<x && !r) {      
    m = root ? max : max-2;
    for(lo=0;lo<m;lo++) 
        d("balk"+(lo+1)).innerHTML = parseInt(le)==parseInt(x+lo) || !root ? "&nbsp;&raquo" : parseInt(x+lo);
}
else if(r) {
    startr(rurl[r-1]);
    ping=1;
    r=0;        
}
else 
    x=1;

[ Voor 55% gewijzigd door Genoil op 30-03-2005 20:21 . Reden: 1.foutje. 2.nog paar regeltjes minder 3. iets beter ]


Verwijderd

Topicstarter
Mithrandir schreef op woensdag 30 maart 2005 @ 18:57:Waarom heb je trouwens zulke slechte variabele-namen?
lo = loop
root = de wortel, als je het complete script ziet dan is dat wel duidelijk.
max = maximum
maar voor de rest ben ik het met je eens dat het niet de beste namen zijn voor variabele.
Mithrandir schreef op woensdag 30 maart 2005 @ 18:53:
JavaScript:
1
knip

is al aardig beter leesbaar, zo lijn ik ze altijd uit...
edit:

En zo kan ook (mits 't in ee nfunctie staat)

JavaScript:
1
knip
het is helaas geen functie, maar ziet er wel stukken beter uit.
Ali_Illegali schreef op woensdag 30 maart 2005 @ 19:00:
[...]

Waarom niet? Volgens mij kan het ook zoals hieronder staat:
code:
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
if( (!r) && (x > 0) && root )
{
  for(lo=0;lo<max;lo++)
  {
    if(parseInt(le)==parseInt(x+lo))
    {
      d("balk"+(lo+1)).innerHTML = "&nbsp;&raquo";
    } 
    else
    {
      d("balk"+(lo+1)).innerHTML = parseInt(x+lo);
    }
  }
}
else if( (!r) && (x > 0) ) 
{
  for(lo=0;lo<(max-2);lo++)
  {
    d("balk"+(lo+1)).innerHTML = "&nbsp;&raquo";
  }
}
else if( !r )
{
  x=1;
}
else 
{
    startr(rurl[r-1]);
    ping=1;
    r=0;
}
daardoor wordt de if-else statement wel vervangen, maar de duidelijkheid wordt wel minder, omdat je bijvoorbeeld 3x (!r), dan had ik één keer een if statement eromheen gezet, en dan vind ik het duidelijker, maar als je dat bij alles doet dan krijg je zo'n code als in mijn startpost.
Genoil schreef op woensdag 30 maart 2005 @ 19:08:
pin me er niet op vast maar volgens mij staat hier hetzelfde:

code:
1
2
3
4
5
6
7
8
9
10
11
12
if(0<x && !r) {      
    if(!root) max-=2;
    for(lo=0;lo<max;lo++) 
        d("balk"+(lo+1)).innerHTML = parseInt(le)==parseInt(x+lo) || !root ? "&nbsp;&raquo" : parseInt(x+lo);
}
else if(r) {
    startr(rurl[r-1]);
    ping=1;
    r=0;        
}
else 
    x=1;
kijk eens aan, dat is persies wat ik bedoelde.
het werkt, het is stukken korter en het gebruikt geen 4 dubbele if-else statement. _/-\o_

hoe pak je zoiets aan? waar begin je en waar let je op?

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
het kan nog korter! :P
code:
1
2
3
4
5
6
7
8
9
10
if(0<x && !r)  
    for(lo=0;lo<(root?max:max-2);lo++) 
       d("balk"+(lo+1)).innerHTML = parseInt(le)==parseInt(x+lo) || !root ? "&nbsp;&raquo" : parseInt(x+lo);
else if(r) {
    startr(rurl[r-1]);
    ping=1;
    r=0;        
}
else 
    x=1;


hoe pak je zoiets aan...kwestie van logica ;)
1. logica analyseren
2. kijken wat er dubbel staat
3. kijken waarom het dubbel staat
4. condities combineren/anders uitdrukken zodat je dubbele dingen kunt strippen
5. zoveel mogelijk if/else vervangen door conditional expressions
6. loze accolades strippen ;)

voorbeelden van dubbele dingen die potentieel gestript kunnen worden:
-gelijksoortige loops
-function calls

condities combineren doe je met || en &&. vaak zijn geneste if else constructies ook te drukken in een 1-laags diepe if/elseif/elseif/else (al heeft JS geen "echte" elseif).

conditional expressions ( expr1 ? expr2 : expr3) worden vaak uitgelegd als een andere vorm van if/else. dat is het ook, maar je kunt er dus ook in 1 keer een waarde (het resultaat van expr2 of expr3) mee uitdrukken, die afhangt van de "waarheid" van expr1.

[ Voor 34% gewijzigd door Genoil op 30-03-2005 20:55 ]


Verwijderd

Topicstarter
k badankt,

die nog kortere met die conditional expressions in de loop vind ik wel weer wat onduidelijker worden.
ik ga die andere gebruiken en wat oefenen met scriptjes verkorten :D

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 10:31

crisp

Devver

Pixelated

JavaScript:
1
for(lo=0;lo<(root?max:max-2);lo++)

ai, nu ga je elke iteratie een conditie afvragen :/
sowieso maakt volgorde hier niet uit, dus zal dit altijd sneller zijn:
JavaScript:
1
2
var lo = root ? max : max - 2;
while (lo--) {   }

Verder maken de conditional comments de code alles behalve duidelijker, dus mijn voorkeur heeft het zeker niet.

Nog een paar netheid en snelheids zaken:
- declareer je variabelen
- geef altijd een base op bij het gebruik van parseInt
- gebruik geen innerHTML als je enkel een nodeValue wilt aanpassen
- voorkom lookups zo veel mogelijk. Als je meerdere keren hetzelfde element in je DOM tree wilt aanspreken cache dan de referentie naar dat object in een global var of array.
- voorkom het gebruik van de NOT operator; reverse logica is meestal moeilijker te begrijpen dan recht-toe-recht-aan logica
- wees duidelijk in je afvragingen, wat bedoel je bijvoorbeeld met:
JavaScript:
1
if (!r) { }

a) wil je weten of r false is?
b) wil je weten of r null is?
c) wil je weten of r 0 is?
d) wil je weten of r '' is?
e) wil je weten of r bestaat?

Nog even over de parseInt:
JavaScript:
1
parseInt(x+lo)

stel nu dat x of lo een string is, dan is het resultaat van x+lo ook een string; er vind dan een concatenatie plaats en dat zal vast niet de bedoeling zijn. Aan de andere kant; als x en lo allebei altijd gewoon numerieke data bevatten (lo bevat dat zeker) is de parseInt natuurlijk puur overbodig.
Een ander truukje om een string om te zetten naar een nummer is dit:
JavaScript:
1
2
var x = '12', lo = 5;
var foo = lo + x/1;

[ Voor 22% gewijzigd door crisp op 30-03-2005 22:57 ]

Intentionally left blank


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
crisp schreef op woensdag 30 maart 2005 @ 22:48:
JavaScript:
1
for(lo=0;lo<(root?max:max-2);lo++)

ai, nu ga je elke iteratie een conditie afvragen :/
hij vroeg niet of het efficient moest blijven, hij vroeg of het korter kon :P
natuurlijk gaat dit nergens over :)

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 09-05 19:34

MBV

'zinloze' {} strippen vind ik een erg foute schrijfstijl. Als je iets aanpast, waarbij je een regeltje toevoegt aan een forloop, zoek je je kleurenblind!
code:
1
2
3
4
5
//veel meer code
for (int i = 1; i < max; i++)
  printf("%d=%c",i,i);
  printf("\n");
//veel meer code

En waarom krijg ik maar 1x een newline? Hier is het duidelijk, maar geloof me, zo'n foutje maak je veel te snel. Ik heb nu al een hekel aan de mogelijkheden qua structuur van Perl, maar ik houd nu al van 1 ding: if(){}else{} is verplicht! Yeah! kan dat nooit meer fout gaan :)

switch-case is alleen een vervanger voor de volgende constructie:
code:
1
2
3
4
5
6
7
8
9
10
11
12
if (x = 1)
{
}
else if (x = 2)
{
}
else if (x = 3)
{
}
else 
{
}

kan vervangen worden door:
code:
1
2
3
4
5
6
7
switch(x)
{
  case 1: break;
  case 2: break; 
  case 3: break;
  default: break;
}

Als het toepasbaar is maak je het eenvoudiger te lezen en verklein je de kans op typo's (behalve die keer dat ik break vergat :X )

over (conditie)?true:false; wil ik het volgende zeggen: ik ben nu voor mijn afstudeerstage bezig met aardig wat tools, boeken e.d. over complexiteit van code, en een van de regels die ik steeds tegen kom voor C++ is dat die dingen vermeden moeten worden. Het enige waar ze echt voor bedoeld zijn en echt tot hun recht komen is als je zoiets hebt:
code:
1
2
$dest_x=($verhouding> 1)?90:90*$verhouding;
$dest_y=($verhouding<=1)?90:90/$verhouding;

Eigenlijk is dit al weer op het randje, ik had ergens een foutje zitten in mijn algoritme waardoor hij niet werkte. Kostte me een uur om hem te vinden. Met een if-statement had het me 7 regels extra gekost met mijn schrijfstijl, maar had ik hem in 1x goed gehad.

Wat bij jouw voorbeeld al had geholpen, was als je de kortste mogelijkheid vooraan zet. Je hebt nu structuur 1 ipv structuur 2:
code:
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
if(conditie){
  if(conditie2)
  {
    //meer condities enz
  }
  else
  {
   //nu de specifieke case waarvoor je de conditie2 nodig had
  }
  //nu de specifieke case waarvoor je conditie1 nodig had
}

//nu mijn manier:
if (!conditie1)
{
  //specifieke case
}
else {
  if (!conditie2)
  {
    //specifieke case
  }
  else {
  //meer zooi
  }
}

je ziet bij 2 veel beter wat waarbij hoort. En waarschijnlijk was jij dan ook op het 'geniale' idee van Genoil gekomen. Ik zou hem niet domweg korter maken, maar meer opschrijven zoals het in je specificatie staat. wazzedat? specificatie? tja, dat leer je nou op de THR :P
Pagina: 1