# (p5js) how can i structure an if then statement so that a few but not all conditions are met?

**URL:** https://discourse.processing.org/t/p5js-how-can-i-structure-an-if-then-statement-so-that-a-few-but-not-all-conditions-are-met/12394
**Category:** Coding Questions
**Created:** [June 30, 2019, 12:55am UTC](https://discourse.processing.org/t/p5js-how-can-i-structure-an-if-then-statement-so-that-a-few-but-not-all-conditions-are-met/12394 "2019-06-30T00:55:03Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![cryptacritic](https://avatars.discourse-cdn.com/v4/letter/c/3d9bf3/32.png) [@cryptacritic](https://discourse.processing.org/u/cryptacritic)
#### Post date: [June 30, 2019, 12:55am UTC](https://discourse.processing.org/t/p5js-how-can-i-structure-an-if-then-statement-so-that-a-few-but-not-all-conditions-are-met/12394/1 "2019-06-30T00:55:03Z")

</div>

Imagine you have ten boolean (or otherwise) variables. You want three of the ten variables to be true, but no more than 3, and no less. You do not want to create a complicated nested if-then function that requires writing out a similar string of code hundreds of times. How do you do it?

Visual Example (I’m pulling this straight from a program i’m writing. Don’t mind the meaning of the variables, just the structure):

if (frameCount % 60 == 0 && (sw1.collect === true || sw2.collect === true || sw3.collect === true || sw4.collect=== true || sw5.collect === true || sw6.collect === true || sw7.collect === true || sw8.collect === true || sw9.collect === true || sw10.collect === true){this.firstCounter = this.firstCounter + 1}

How can i write the above conditional to only accept (no more and no less than) 3 of these “collect” variables as true?

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [June 30, 2019, 2:05am UTC](https://discourse.processing.org/t/p5js-how-can-i-structure-an-if-then-statement-so-that-a-few-but-not-all-conditions-are-met/12394/2 "2019-06-30T02:05:12Z")

</div>

```auto
"use strict";

class SW {
  constructor() {
    this.randomCollect();
  }

  randomCollect() {
    this.collect = Math.random() < .5;
  }

  static reducer(trues, { collect }) {
    return trues + collect;
  }

  static getNumTrues(swArr) {
    return swArr.reduce(SW.reducer, 0);
  }
}

const TRUES = 3, SWS = 10, sws = Array.from({ length: SWS }, () => new SW);
console.log(sws);

const swTrues = SW.getNumTrues(sws);
console.log(`We've got ${ swTrues } true collects.`);

if (swTrues === TRUES) console.log(`We have exactly ${ TRUES } true collects!`);
else console.log(`We don't have ${ TRUES } true collects.`);

```

> **[Array.from()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from)**
>
> The Array.from() method creates a new, shallow-copied Array instance from an array-like or iterable object.

> **[Array.prototype.reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce)**
>
> The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.

---

<div class="post-metadata">

### Author: ![cryptacritic](https://avatars.discourse-cdn.com/v4/letter/c/3d9bf3/32.png) [@cryptacritic](https://discourse.processing.org/u/cryptacritic)
#### Post date: [June 30, 2019, 7:56am UTC](https://discourse.processing.org/t/p5js-how-can-i-structure-an-if-then-statement-so-that-a-few-but-not-all-conditions-are-met/12394/3 "2019-06-30T07:56:38Z")

</div>

I’m having a hard time digesting your write-up. To give you more context, sw1, sw2, etc… are variables in setup that reference classes in and of themselves. Are you saying i need to create a new class outside of these? My main confusion is how does this get included in my conditional statement?

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [June 30, 2019, 9:59am UTC](https://discourse.processing.org/t/p5js-how-can-i-structure-an-if-then-statement-so-that-a-few-but-not-all-conditions-are-met/12394/4 "2019-06-30T09:59:02Z")

</div>

Basically count how much are true:

counter =0;

if(sw1) counter++;  
if(sw2…

and then

if(counter==3) …

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [June 30, 2019, 12:21pm UTC](https://discourse.processing.org/t/p5js-how-can-i-structure-an-if-then-statement-so-that-a-few-but-not-all-conditions-are-met/12394/5 "2019-06-30T12:21:57Z")

</div>

> [@cryptacritic](#):
>
> To give you more context, _sw1_, _sw2_, etc… are variables in **setup()** that reference classes in and of themselves.

Whenever we’ve got a sequence of variables like this: _var0_, _var1_, _var2_, _var3_…

The most practical & sane thing to do is to create a single array container to replace them all:  
`const arr = [];`

In my posted example I’ve chosen [[u]Array[/u].**from()**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) in order to both create & populate the _sws[]_ array:

> [@GoToLoop](#):
>
> `const sws = Array.from({ length: 10 }, () => new SW);`

But given there are many ways to create & populate a JS array, you can easily pick some other technique:

> **[Array - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)**
>
> The Array object, as with arrays in other programming languages, enables storing a collection of multiple items under a single variable name, and has members for performing common array operations.

> [@cryptacritic](#):
>
> Are you saying I need to create a new class outside of these?

My posted class **_SW_** is merely an attempt mockup of your currently unrevealed class.

Most I can dig up from your post is that your secret class got a boolean property named _collect_, nothing more.

Obviously your actual class probably got a diff. name and much more stuff in it.

BtW, my posted example is fully runnable, w/o any need of additional libraries, not even p5js!  
Just open a browser’s console, then copy & paste my code in it.

> [@cryptacritic](#):
>
> My main confusion is how does this get included in my conditional statement?

The coolest thing about containers is that once we’ve got all of our values stored in 1, we can easily iterate over them using all kinds of `for ()` loops and even call methods such as Array::**forEach()** and many others like it:

> **[for - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for)**
>
> The for statement creates a loop that consists of three optional expressions, enclosed in parentheses and separated by semicolons, followed by a statement (usually a block statement) to be executed in the loop.

> **[for...in - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in)**
>
> The for...in statement iterates over all enumerable string properties of an object (ignoring properties keyed by symbols), including inherited enumerable properties.

> **[for...of - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)**
>
> The for...of statement executes a loop that operates on a sequence of values sourced from an iterable object. Iterable objects include instances of built-ins such as Array, String, TypedArray, Map, Set, NodeList (and other DOM collections), as well...

> **[Array.prototype.forEach() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)**
>
> The forEach() method of Array instances executes a provided function once
> for each array element.

And as @Chrisir’s stated in his reply:

> [@Chrisir](#):
>
> Basically _count_ how many are `true`:

In my own example code I’ve written a `static` method inside class _ **SW** _ named **getNumTrues()**, which requires a passed array argument of datatype _ **SW** _, and then returns how many `true` values it had found stored in the property _collect_ of each _ **SW** _ element of the passed array:

> [@GoToLoop](#):
>
> ```auto
> static getNumTrues(swArr) {
> return swArr.reduce((trues, { collect }) => trues + collect, 0);
> }
> 
> ```

As you can see, I’ve chosen the method Array::**reduce()** in order to iterate on each _ **SW** _ element of the passed array:

> **[Array.prototype.reduce() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce)**
>
> The reduce() method of Array instances executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer...

But I coulda easily picked something else.  
For example, here’s the same method rewritten using a [`for..of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) loop instead:

```auto
static getNumTrues(swArr) {
  let trues = 0;
  for (const { collect } of swArr) collect && ++trues;
  return trues;
}

```

Now that we’ve got ourselves a functioning **getNumTrues()** method, you can rewrite your original posted conditional statement like this:  
`if (!(frameCount % 60) && SW.getNumTrues(sws) === 3) ++this.firstCounter;`

---

<div class="post-metadata">

### Author: ![cryptacritic](https://avatars.discourse-cdn.com/v4/letter/c/3d9bf3/32.png) [@cryptacritic](https://discourse.processing.org/u/cryptacritic)
#### Post date: [July 1, 2019, 1:29am UTC](https://discourse.processing.org/t/p5js-how-can-i-structure-an-if-then-statement-so-that-a-few-but-not-all-conditions-are-met/12394/6 "2019-07-01T01:29:53Z")

</div>

Man i’d really like a simpler solution than this, especially since im wanting to reproduce this 3 or 4 times for the same classes sw1, sw2, etc…

I was inspired to use a for loop, but it didn’t seem to work the way i thought it would. It doesn’t seem to be reading the code right. Is there a way to do it more like this?:

for (swx2 = 1; swx2 \<=10; swx2=swx2+1){  
for (swx = 1; swx \<= 10; swx=swx+1){  
if (‘sw’+swx+‘collect’ === true && ‘sw’+swx2+‘collect’ === true) {console.log(‘it works’)}  
}}

My console woudn’t log the “it works”. Although if it did then i could plug in the rest. Is there something fundamentally wrong with this piece of code, or just with the way i’ve written it?

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [July 1, 2019, 3:11pm UTC](https://discourse.processing.org/t/p5js-how-can-i-structure-an-if-then-statement-so-that-a-few-but-not-all-conditions-are-met/12394/7 "2019-07-01T15:11:48Z")

</div>

> [@cryptacritic](#):
>
> I’m wanting to reproduce this 3 or 4 times for the same classes _sw1_, _sw2_, etc…

Ru sure _sw1_, _sw2_, etc… are indeed classes? They seem like variables to me.  
Aren’t you mixing up what is a class and what is an object created by a class?

> [@cryptacritic](#):
>
> I was inspired to use a for loop,

I see 2 `for ( ; ; )` loops and not just 1. Why do you need a double loop for there?

> [@cryptacritic](#):
>
> My console wouldn’t log the “it works”.

- I see you’re concatenating strings to a variable: `'sw' + swx + 'collect'`.
- Then using the strict identity version of the equality comparison operator [`===`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Identity).
- In order to compare the resultant string to the boolean value `true`.
- B/c a string isn’t a boolean, the operator `===` will always evaluate those operands as `false`!
- In short, there’s no way your conditional will ever log “it works”!

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [July 1, 2019, 7:54pm UTC](https://discourse.processing.org/t/p5js-how-can-i-structure-an-if-then-statement-so-that-a-few-but-not-all-conditions-are-met/12394/8 "2019-07-01T19:54:51Z")

</div>

Didn’t you like my approach?

When it doesn’t matter which variables are `true` but only that there are 3 that are `true`, just **count** them and evaluate the result.

---

<div class="post-metadata">

### Author: ![cryptacritic](https://avatars.discourse-cdn.com/v4/letter/c/3d9bf3/32.png) [@cryptacritic](https://discourse.processing.org/u/cryptacritic)
#### Post date: [July 4, 2019, 11:35pm UTC](https://discourse.processing.org/t/p5js-how-can-i-structure-an-if-then-statement-so-that-a-few-but-not-all-conditions-are-met/12394/9 "2019-07-04T23:35:25Z")

</div>

Thank you so much for your replies. My code is too dispersed to cleanly share it, but basically, i was able to do as suggested, and count how many of the variables are true. I ended up having to use nested timers (to ensure i was counting my variables once and not repeatedly), and i had to attribute a timer to each variable. To do what i was trying to do, i had to compare ordinal timers with the specific ones. The point of this was for me to structure a three-slot visual template, where performing some event 1-15 (since this is a computer game, it was collecting secondary weapons), and recording the results in the first unfilled slot (showing what sw you have, and the details of such) So far ive got everything working expectedly now. 😄 If you are curious of my game so far, you can see the game itself (not the code) in active development. Its a slow progress, but if you’re curious: [https://editor.p5js.org/cryptacritic17/full/oaswueydz](https://editor.p5js.org/cryptacritic17/full/oaswueydz)

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [July 4, 2019, 11:57pm UTC](https://discourse.processing.org/t/p5js-how-can-i-structure-an-if-then-statement-so-that-a-few-but-not-all-conditions-are-met/12394/10 "2019-07-04T23:57:01Z")

</div>

> [@cryptacritic](#):
>
> I ended up having to use nested timers (to ensure i was counting my variables once and not repeatedly), and i had to attribute a timer to each variable. To do what i was trying to do, i had to compare ordinal timers with the specific ones. The point of this was for me to structure a three-slot visual template, where performing some event 1-15 (since this is a computer game, it was collecting secondary weapons), and recording the results in the first unfilled slot (showing what sw you have, and the details of such)

Hmm. I’m confused by what all of this (nested timers, 15 variables, etc.) has to do with populating three slots with falling objects. It sounds extremely complex. Can’t you just compare a randomly generated object to the slot contents on spawn and/or on touch?

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [July 5, 2019, 2:24am UTC](https://discourse.processing.org/t/p5js-how-can-i-structure-an-if-then-statement-so-that-a-few-but-not-all-conditions-are-met/12394/11 "2019-07-05T02:24:56Z")

</div>

Your code is still using variables w/ numbered names instead of creating 1 array for them. 😐

Although written for Processing Java, the article below explains how to convert multiple variables into an array: 🤓

- [Forum.Processing.org/two/discussion/8082/from-several-variables-to-arrays](http://Forum.Processing.org/two/discussion/8082/from-several-variables-to-arrays)
