1 /** 2 Flattens a range one level deep by removing non truthy values. 3 */ 4 module ddash.algorithm.flatten; 5 6 /// 7 unittest { 8 auto arrayOfArrays = [[[1]], [[]], [[2], [3]], [[4]]]; 9 10 // remove emptys 11 assert(arrayOfArrays.flatten.equal([[1], [], [2], [3], [4]])); 12 assert([[1], [], [2, 3], [4]].flatten.equal([1, 2, 3, 4])); 13 14 // remove empty all the way down 15 assert(arrayOfArrays.flattenDeep.equal([1, 2, 3, 4])); 16 17 import optional; 18 assert([some(some(3)), no!(Optional!int), some(some(2))].flattenDeep.equal([3, 2])); 19 } 20 21 import ddash.common; 22 23 /** 24 Flattens a range one level deep by removing anything that's empty 25 26 Params: 27 range = an input range 28 29 Returns: 30 A flattened range 31 32 Since: 33 0.0.1 34 */ 35 auto flatten(Range)(Range range) if (from!"std.range".isInputRange!Range) { 36 import std.range: ElementType, isInputRange; 37 static if (isInputRange!(ElementType!Range)) 38 { 39 import std.algorithm: joiner; 40 return range.joiner; 41 } 42 else 43 { 44 return range; 45 } 46 } 47 48 unittest { 49 assert([[[1]], [[]], [[2], [3]], [[4]]].flatten.equal([[1], [], [2], [3], [4]])); 50 assert([[1], [], [2, 3], [4]].flatten.equal([1, 2, 3, 4])); 51 } 52 53 unittest { 54 import optional; 55 assert([some(3), no!int, some(2)].flatten.equal([3, 2])); 56 assert([some(some(3)), no!(Optional!int), some(some(2))].flatten.equal([some(3), some(2)])); 57 } 58 59 /** 60 Flattens a range all the way down 61 62 Params: 63 range = an input range 64 65 Returns: 66 A flattened range 67 68 Since: 69 0.0.1 70 */ 71 auto flattenDeep(Range)(Range range) if (from!"std.range".isInputRange!Range) { 72 import std.range: ElementType, isInputRange; 73 import ddash.algorithm: flatten; 74 static if (isInputRange!(ElementType!Range)) 75 { 76 return range 77 .flatten 78 .flattenDeep; 79 } 80 else 81 { 82 return range.flatten; 83 } 84 }