Description
A different approach into handling strings. This case is useful 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 separate components into 2 lists. The PartialStringIndex class stores the partial string and the index (which is the priority used to recompose).
Goal
For example given the expression "abc123def456" you can separate the string by rule char is number — the class will provide 2 lists: {"abc", "def"} and {"123", "456"}.
Usage is:
csharp
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
csharp
public class StringDestructure
{
private class PartialStringIndex
{
public string Context;
public int Index;
}
//Collection of separated 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 an altering action for partial strings that meet condition
public StringDestructure OnConditionMet(Func<string, string> func)
{
this.ActionsOnConditionMet.Add(func);
return this;
}
//Add an 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));
}
}