Description
A different approach into handling strings. This case is usefull when you want to alter parts of a string depending on char types. For example numbers in a string.
The principle is simple. Iterate through the string and sepparate components into 2 lists. Class PartialStringIndex will store the partial string and the index (which is priority to recompose)
Goal
For example given the expression “abc123def456” you can sepparate the string by rule char is number, the class will provide 2 lists: {“abc”, “def”} and {“123”, “456”}.
Usage is:
1 2 3 4 5 6 |
Regex regex = new Regex("[0-9]"); StringDestructure sd = StringDestructure.By("abc123def456", (ch) => regex.Match(ch.ToString()).Success); sd.OnConditionMet((str) => str); sd.OnConditionNotMet((str) => str.ToUpper()); string result = sd.Recompose(); ///THE RESULT WILL BE "ABC123DEF456" |
Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
public class StringDestructure { private class PartialStringIndex { public string Context; public int Index; } //Collection of sepparated elements List ElementsMeetCondition; List ElementsDoNotMeetCondition; //altering actions on each of them List<Func<string, string>> ActionsOnConditionMet; List<Func<string, string>> ActionsOnConditionNotMet; private StringDestructure(string Context, Predicate predicate) { ElementsMeetCondition = new List(); ElementsDoNotMeetCondition = new List(); ActionsOnConditionMet = new List<Func<string, string>>(); ActionsOnConditionNotMet = new List<Func<string, string>>(); StringBuilder temporary = new StringBuilder(); bool storeToCondition = false; int recomposeIndex = 0; for(int i = 0; i < Context.Length;i++) { char ch = Context[i]; if (i == 0) { if (predicate(ch)) { temporary.Append(ch); storeToCondition = true; } else { temporary.Append(ch); storeToCondition = false; } } else { if (predicate(ch)) { if (storeToCondition) { temporary.Append(ch); } else { ElementsDoNotMeetCondition.Add(new PartialStringIndex { Context = temporary.ToString(), Index = recomposeIndex }); recomposeIndex++; temporary.Clear(); temporary.Append(ch); } storeToCondition = true; } else//if (!predicate(ch) { if (storeToCondition) { ElementsMeetCondition.Add(new PartialStringIndex { Context = temporary.ToString(), Index = recomposeIndex }); recomposeIndex++; temporary.Clear(); temporary.Append(ch); } else { temporary.Append(ch); } storeToCondition = false; } } if (i == Context.Length - 1) { if (storeToCondition) ElementsMeetCondition.Add(new PartialStringIndex { Context = temporary.ToString(), Index = recomposeIndex }); else ElementsDoNotMeetCondition.Add(new PartialStringIndex { Context = temporary.ToString(), Index = recomposeIndex }); } } } //Initializer public static StringDestructure By(string Context, Predicate ListSplitCondition) { return new StringDestructure(Context, ListSplitCondition); } //Add am altering action for partial strings that meet condition public StringDestructure OnConditionMet(Func<string, string> func) { this.ActionsOnConditionMet.Add(func); return this; } //Add am altering action for partial strings that do not meet condition public StringDestructure OnConditionNotMet(Func<string, string> func) { this.ActionsOnConditionNotMet.Add(func); return this; } public string Recompose() { foreach(var item in this.ElementsMeetCondition) { string partialString = item.Context; foreach (var action in this.ActionsOnConditionMet) { partialString = action(partialString); } item.Context = partialString; } foreach (var item in this.ElementsDoNotMeetCondition) { string partialString = item.Context; foreach (var action in this.ActionsOnConditionNotMet) { partialString = action(partialString); } item.Context = partialString; } List allitems = this.ElementsMeetCondition.Concat(this.ElementsDoNotMeetCondition).ToList(); Comparison comparison = (first, second) => { return first.Index.CompareTo(second.Index); }; allitems.Sort(comparison); return string.Concat(allitems.Select(x => x.Context)); } } |