Thread overview
Is a shorter statement possible in this case?
Nov 05
Ctn-Dev
Nov 06
user1234
November 05

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?

November 06

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:

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.

November 06

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:

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);
}
November 06

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:

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);
}