root/trunk/src/semitwist/util/array.d

Revision 185, 2.8 kB (checked in by Abscissa, 1 year ago)

(B) util: Removed obsolete D2/Phobos compatibility modules (and some minor cleanups).

  • Property svn:eol-style set to native
Line 
1 // SemiTwist Library
2 // Written in the D programming language.
3
4 module semitwist.util.array;
5
6 import std.algorithm;
7 import std.array;
8 import std.functional;
9
10 import semitwist.util.all;
11
12 size_t maxLength(T)(T[][] arrays)
13 {
14     size_t maxLen=0;
15     foreach(T[] array; arrays)
16         maxLen = max(maxLen, array.length);
17     return maxLen;
18 }
19
20 size_t indexOfMin(T)(T[] array)
21 {
22     T best = T.max;
23     size_t bestIndex;
24     foreach(size_t i, T elem; array)
25     {
26         if(elem < best)
27         {
28             best = elem;
29             bestIndex = i;
30         }
31     }
32     return bestIndex;
33 }
34
35 size_t indexOfMax(T)(T[] array)
36 {
37     T best = T.min;
38     size_t bestIndex;
39     foreach(size_t i, T elem; array)
40     {
41         if(elem > best)
42         {
43             best = elem;
44             bestIndex = i;
45         }
46     }
47     return bestIndex;
48 }
49
50 //TODO: eliminate name collision with tango.text.Util
51 //TODO: Is this the same as tango.core.Array.findIf()?
52 /+size_t find(T)(T[] collection, bool delegate(T[], size_t) isFound, size_t start=0)
53 {
54     for(size_t i=start; i<collection.length; i++)
55     {
56         if(isFound(collection, i))
57             return i;
58     }
59     
60     return collection.length;
61 }
62 +/
63 size_t findPrior(T)(T[] collection, bool delegate(T[], size_t) isFound, size_t start=(size_t).max)
64 {
65     if(start == (size_t).max)
66         start = collection.length-1;
67        
68     for(size_t i=start; i >= 0; i--)
69     {
70         if(isFound(collection, i))
71             return i;
72     }
73
74     return collection.length;
75 }
76
77 /// Returns everything in 'from' minus the values in 'except'.
78 // Note: using ref didn't work when params were (const string[] here).dup
79 T allExcept(T)(T from, T except)
80 {
81     T f = from.dup;
82     T e = except.dup;
83     f.sort();
84     e.sort();
85     return f.missingFrom(e);
86 }
87 T[] allExcept(T)(T[] from, T except)
88 {
89     return allExcept(from, [except]);
90 }
91
92 /// Ex: toRangedPairs([3,4,5,5,6,6,10,25,26]) == [[3,6], [10,10], [25,26]]
93 /// Only intended for integer types and other ordered types for which "x+1" makes sense.
94 /// Input does not have to be sorted.
95 /// The resulting pairs are sorted and are inclusive on both ends.
96 /// Optionally takes a splitCond predicate so you can customize when the range ends.
97 T[2][] toRangedPairs(alias splitCond = "b > a + 1", T)(T[] arr)
98 {
99     alias binaryFun!(splitCond) splitCondDg;
100     static if(!is(typeof(splitCondDg(T.init, T.init)) == bool))
101         static assert(false, "Invalid predicate passed to toRangedPairs: "~splitCond);
102
103     if(arr.length == 0)
104         return [];
105    
106     if(arr.length == 1)
107         return [ [ arr[0], arr[0] ] ];
108        
109     arr = array(sort(arr));
110    
111     T[2][] ret;
112     auto prevVal  = arr[0];
113     auto startVal = arr[0];
114     foreach(val; arr[1..$])
115     {
116         if(splitCondDg(prevVal, val))
117         {
118             ret ~= [ startVal, prevVal ];
119             startVal = val;
120         }
121         prevVal = val;
122     }
123     ret ~= [ startVal, arr[$-1] ];
124    
125     return ret;
126 }
127
128 mixin(unittestSemiTwistDLib(q{
129
130     // toRangedPairs
131     mixin(deferEnsure!(q{ [12,3,7,4,10,5,9,12].toRangedPairs() }, q{ _ == [[3,5], [7,7], [9,10], [12,12]] }));
132     mixin(deferEnsure!(q{ [1,20].toRangedPairs() }, q{ _ == [[1,1], [20,20]] }));
133
134 }));
Note: See TracBrowser for help on using the browser.