digitalmars.D.learn - Is a shorter statement possible in this case?
- Ctn-Dev (27/27) Nov 05 2023 I wrote this earlier:
- Andrey Zherikov (12/13) Nov 05 2023 Try this:
- user1234 (32/38) Nov 05 2023 Yes, assuming you accept to drop your string arrays then one is
- Paul Backus (32/37) Nov 06 2023 If sorting the arrays is an option, you can use `setIntersection`
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
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
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
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