www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is a shorter statement possible in this case?

reply Ctn-Dev <wanderingMesos protonmail.com> writes:
I wrote this earlier:

```
import std.stdio;
import std.algorithm.searching;

string[] numeric_traits_1 = [];
string[] numeric_traits_2 = ["Two"];
string[] numeric_traits_3 = ["One"];
string[] numeric_traits_4 = ["One", "Two"];

void main() {

     void numeric_traits_contains(string[] numeric) {
         if(numeric.canFind("One") & numeric.canFind("Two")) {
             writeln("Array contains 'One' and 'Two'.");
         } else if(numeric.canFind("One", "Two")) {
             writeln("Array contains 'One' or 'Two'.");
         } else {
             writeln("Array contains neither 'One' nor 'Two'");
         }
     }

     numeric_traits_contains(numeric_traits_1);
     numeric_traits_contains(numeric_traits_2);
     numeric_traits_contains(numeric_traits_3);
     numeric_traits_contains(numeric_traits_4);
}
```

`if` runs when both "One" and "Two" are in the given array as 
intended, but its conditional statement looks verbose. Is there a 
more concise way of getting the same result?
Nov 05 2023
next sibling parent Andrey Zherikov <andrey.zherikov gmail.com> writes:
On Sunday, 5 November 2023 at 18:36:40 UTC, Ctn-Dev wrote:

 Is there a more concise way of getting the same result?
Try this: ```d switch(range.map!(_ => (_== "Two" ? 2 : _=="One" ? 1 : 0)).fold!((a,b) => a | b)(0)) { case 3: writeln("both"); break; case 2: writein("only two"); break; case 1: writeln("only one"); break; default: writeln("none"); break; } ``` Where `range` is input array.
Nov 05 2023
prev sibling next sibling parent user1234 <user1234 12.de> writes:
On Sunday, 5 November 2023 at 18:36:40 UTC, Ctn-Dev wrote:
 I wrote this earlier:

 [...]
 
 if runs when both "One" and "Two" are in the given array as 
 intended, but its conditional statement looks verbose. Is there 
 a more concise way of getting the same result?
Yes, assuming you accept to drop your string arrays then one is to use bit flags: ```d enum NumTraitBits { Empty, One = 0x01, Two = 0x02, Three = 0x04, // ... _ = 0xF0 } NumTraitBits numeric_traits_1 = NumTraitBits.Empty; NumTraitBits numeric_traits_2 = NumTraitBits.Two; NumTraitBits numeric_traits_3 = NumTraitBits.One; NumTraitBits numeric_traits_4 = NumTraitBits.Two | NumTraitBits.One; void main() { import std.stdio, std.traits; void numeric_traits_contains(NumTraitBits numeric) { write("contains: "); foreach (i; EnumMembers!NumTraitBits) if (numeric & i) write(" ", i); writeln(); } numeric_traits_contains(numeric_traits_1); numeric_traits_contains(numeric_traits_2); numeric_traits_contains(numeric_traits_3); numeric_traits_contains(numeric_traits_4); } ```
Nov 05 2023
prev sibling parent Paul Backus <snarwin gmail.com> writes:
On Sunday, 5 November 2023 at 18:36:40 UTC, Ctn-Dev wrote:
 I wrote this earlier:

 [...]

 `if` runs when both "One" and "Two" are in the given array as 
 intended, but its conditional statement looks verbose. Is there 
 a more concise way of getting the same result?
If sorting the arrays is an option, you can use `setIntersection` from `std.algorithm.setops`, which returns the overlap between two sorted ranges: ```d import std.stdio; import std.algorithm.searching: count; import std.algorithm.setops: setIntersection; import std.algorithm.sorting: sort; string[] numeric_traits_1 = []; string[] numeric_traits_2 = ["Two"]; string[] numeric_traits_3 = ["One"]; string[] numeric_traits_4 = ["One", "Two"]; void main() { void numeric_traits_contains(string[] numeric) { sort(numeric); // required by setIntersection size_t howMany = setIntersection(numeric, ["One", "Two"]).count; if (howMany == 2) { writeln("Array contains 'One' and 'Two'."); } else if(howMany == 1) { writeln("Array contains 'One' or 'Two'."); } else { writeln("Array contains neither 'One' nor 'Two'"); } } numeric_traits_contains(numeric_traits_1); numeric_traits_contains(numeric_traits_2); numeric_traits_contains(numeric_traits_3); numeric_traits_contains(numeric_traits_4); } ```
Nov 06 2023