How to get the intermediate portion of string? - c#

I have a string as under
var input= "dbo.xyx.v1.UserDefinedFunction";
The desired output will be "xyx.v1";
My attempt is
var input = "dbo.xyx.v1.UserDefinedFunction";
var intermediate = input.Split('.').Skip(1);
var res = intermediate.Reverse().Skip(1).Aggregate((a, b) => b + "." + a);
works fine..but any other proper and elegant method?
Kindly note that it can be any part(in the example I just showed 4 parts)
e.g.
Input : "dbo.part1.part2.part3.part4.UserDefinedFunction"
Output : "part1.part2.part3.part4"

This returns always the mid part of a string which can be one or two parts(acc. to the total part-number).
var input = "dbo.xyx.v1.UserDefinedFunction";
string[] tokens = input.Split('.');
int midIndex = (tokens.Length - 1) / 2;
IEnumerable<int> midIndices = midIndex % 2 == 0
? new[] { midIndex }
: new[] { midIndex, midIndex + 1 };
string mid = string.Join(".", tokens.Where((t, i) => midIndices.Contains(i)));
Demo
So in this case it returns xyx.v1, for a string bo.xyx.v1 it returns v1 since that's the only mid-part.

string output= input.Substring(input.IndexOf('.') + 1,
input.LastIndexOf('.') - input.IndexOf('.') - 1);

var input = "dbo.xyx.v1.UserDefinedFunction";
var start = input.IndexOf('.');
var end = input.LastIndexOf('.');
string output;
if (start < end)
{
output = input.Substring(start+1, end-start-1);
}
else
{
output = input;
}

If you need to use LINQ, you can use Skip(1).Take(2) and string.Join, like this:
var parts = input.Split('.');
var res = string.Join(".", parts.Skip(1).Take(parts.Length-2));
If you need to throw away the first and the last parts, then you can use Substring, like this:
var start = input.IndexOf('.')+1;
var end = input.LastIndexOf('.')-1;
var res = input.Substring(start, end-start+1);
Finally, you can use regular expression, like this:
var res = Regex.Replace(input, "^[^.]+[.](.+)[.][^.]+$", "$1");

var input = "dbo.xyx.v1.UserDefinedFunction";
var res = string.Join(".", input.Split('.').Skip(1).Take(2));

You could simplify it and do:
var split = input.Split(".");
var result = String.Join(".", split[1], split[2]);
No need for Skip or Take.

var input = "dbo.xyx.v1.UserDefinedFunction";
var intermediate = input.Split('.');
var res = string.Join(".", intermediate[1],intermediate[2]);
EDIT: for any part version
var res = string.Join(".", intermediate.Skip(1).Take(intermediate.Length - 2));

[TestClass]
public class UnitTest2
{
[TestMethod]
public void TestMethod1()
{
var ret = "this.is.my.test.string".MySplit(".", new int[] {0,1,4 });//this.is.string
}
}
public static class Process {
public static string MySplit(this string Source, string seprator, int[] positionTokeep) {
var items = Source.Split(seprator.ToCharArray());
string ret = string.Empty;
for (int i = 0; i < positionTokeep.Length; i++) {
ret += items[positionTokeep[i]] + seprator;
}
if (!string.IsNullOrWhiteSpace(ret)) {
ret = ret.Substring(0,ret.Length - seprator.Length);
}
return ret;
}
}

Related

how do find the same string and difference string in List<string>?

I have list like this:
List<string> myList = new List<string>()
{
"AS2258B43C014AI9954803",
"AS2258B43C014AI9954603",
"AS2258B43C014AI9954703",
"AS2258B43C014AI9954503",
"AS2258B43C014AI9954403",
"AS2258B43C014AI9954203",
"AS2258B43C014AI9954303",
"AS2258B43C014AI9954103",
};
I want to output something format is sameString+diffString0\diffString1\diffString2.... like this "AS2258B43C014AI9954803\603\703\503\403\203\303\103"
what should I do?
You can create a method which returns you the difference between to strings:
private static string GetDiff (string s1, string s2)
{
int i;
for(i = 0; i < Math.Min(s1.Length,s2.Length); i++)
{
if(s1[i] != s2[i])
{
break;
}
}
return s2.Substring(i);
}
This method iterats until the first character which is different and returns the remaining characters of the second string.
With that method, you can obtain your result with the LINQ query:
string first = myList[0];
string result = first + "/" + string.Join("/", myList.Skip(1).Select(x => GetDiff(first,x)));
Online demo: https://dotnetfiddle.net/TPkhmz
Alphanumeric sorting using LINQ
Create static method for pads
public static string PadNumbers(string input)
{
return Regex.Replace(input, "[0-9]+", match => match.Value.PadLeft(10, '0'));
}
then call it
var result = myList.OrderBy(x => PadNumbers(x));
after that you can find the difference
The simplest solution is to create a function like this :
public static string Output(List<String> ListString)
{
string sameString = ListString.First().Substring(0, 18);
string output = sameString;
foreach (var item in ListString)
{
output += item.Substring(19);
output += "\\";
}
return output.Substring(0, output.Length - 1);
}

Split string into substrings based on the separator from the left

In c#, is there an elegant way to split a string like "a.b.c" into a, a.b, a.b.c
The number of separators are not fixed so it could be "a.b" which will output {a, a.b} or "a.b.c.d" which will output {a, a.b, a.b.c, a.b.c.d}.
The only thing I can think of is split the string into individual components and then concatenate it again.
This is what I have so far:
var fieldNames = new List<string>();
var fieldSeparator ='.';
var myString = "a.b.c.d";
var individualFields = myString.Split(fieldSeparator);
string name = "";
foreach(var fieldName in individualFields)
{
name = string.IsNullOrEmpty(name) ? fieldName : $"{name}{fieldSeparator}{fieldName}";
fieldNames.Add(name);
}
Maybe this extension?
public static string[] SplitCombineFirst(this string str, params string[] delimiter)
{
string[] tokens = str.Split(delimiter, StringSplitOptions.RemoveEmptyEntries);
var allCombinations = new List<string>(tokens.Length);
for(int take = 1; take <= tokens.Length; take++)
{
string combination = string.Join(delimiter[0], tokens.Take(take));
allCombinations.Add(combination);
}
return allCombinations.ToArray();
}
Call:
string[] result = "a.b.c".SplitCombineFirst(".");
This looks like a classic case for recursion.
List<string> splitCombine(string source, string delimiter, int startIndex)
{
List<string> result = new List<string>();
var indx = source.IndexOf(delimiter, startIndex);
if (indx >= 0)
{
if (indx > 0)
{
result.Add(source.Substring(0, indx));
}
result.AddRange(splitCombine(source, delimiter, ++indx));
}
else
{
result.Add(source);
}
return result;
}
Call:
var result = splitCombine("a.b.c.d.e", ".", 0);

Declaring variable in splitted string in c# and search the db row between those strings

I have an requirement like search functionality,
Edit: Search is like set of varchars usually this ID contains values like C001,C002,...
so if user is entering the ranges like C001-C010 it should search all the rows in oracle db in between that C001-C010 this is what my requirement.
If user is entering some ranges like C001-C010 in text box this should be splited as two variables and it should search all the elements in between this range.
How to do this. I think using Enumerator range we can do this but i am facing problem like splitting strings needs to declared as separate variable and search between that. which I cant achieve.
sample code is below.
else if (!_search.MultipleId.Contains('-'))
{
filterExp = filterExp.And(x => x.Id.Contains(_search.MultipleId));
}
If the Id is in format of CXXX then you can do something like this:
if(_search.MultipleId.Contain("-"))
{
var range = _search.MultipleId.Split('-');
filterExp = filterExp.And(x => x.Id >= range[0] && x.Id <= range1);
}
Not knowing all of you business requirements, you could try something like this:
class Program
{
static void Main(string[] args)
{
var items = new List<string> { "C001", "C010" };
var firstChar = new List<string>();
var remainingChars = new List<string>();
items.ForEach(i =>
{
firstChar.Add(i[0].ToString());
remainingChars.Add(i.Substring(1));
});
firstChar.ForEach(f => { Console.Write(f + " "); });
Console.WriteLine();
remainingChars.ForEach(r => { Console.Write(r + " "); });
Console.WriteLine();
//Prints the following
//C C
//001 010
//Press any key to continue . . .
}
}
Something like this might help:
var pair = yourstring.Split('-')
.Select(a => new { one= a[0], two= a[1]});
I would cast the dataset to a list so I could use the indices of the start and end args.
var items = dataset.ToList();
var searchString = "B1, C10";
var removedWhitespace = Regex.Replace(searchString, #"\s+", "");
var rangeToSearch = removedWhitespace.Split(',');
var startPosition = items.FindIndex(x => x.ID == rangeToSearch.First());
var endPosition = items.FindIndex(x => x.ID == rangeToSearch.Last());
var selectedItems =
items.Skip(startPosition).Take(endPosition - startPosition + 1); // +1 to include the original id's
If you have to you can order the list, but one caveat with this method is that the list is ordered alphabetically, so you may have to do some additional processing to make sure that you return all the values in the range.
public static HashSet<string> getIdsFromRangeQuery(string multipleIds)
{
multipleIds = multipleIds.ToUpper().Replace(" ", "");
HashSet<string> inSet = new HashSet<string>();
string[] parts = multipleIds.Split(new[] { ";" }, StringSplitOptions.None);
foreach (string part in parts)
{
Regex rgx = new Regex(#"^M([0 - 9] +)C([0 - 9] +)$");
Regex rgxTwo = new Regex(#"^M([0-9]+)C([0-9]+)-M([0-9]+)C([0-9]+)$");
Regex rgxThree = new Regex(#"^[0-9]+$");
Regex rgxFour = new Regex(#"^([0-9]+)-([0-9]+)$");
if (rgx.IsMatch(part))
{
inSet.Add(part);
}
else if (rgxTwo.IsMatch(part))
{
string[] fromTo = part.Split(new[] { "-" }, StringSplitOptions.None);
int mFrom = int.Parse(fromTo[0].Substring(1, fromTo[0].IndexOf("C")));
int mTo = int.Parse(fromTo[1].Substring(1, fromTo[1].IndexOf("C")));
int cFrom = int.Parse(fromTo[0].Substring(fromTo[0].LastIndexOf("C") + 1));
int cTo = int.Parse(fromTo[1].Substring(fromTo[1].LastIndexOf("C") + 1));
for (int i = mFrom; i <= mTo; i++)
{
for (int j = cFrom; j <= cTo; j++)
{
inSet.Add("M" + i + "C" + j);
}
}
}
else if (rgxThree.IsMatch(part))
{
inSet.Add(part);
}
else if (rgxFour.IsMatch(part)
{
string[] fromTo = part.Split(new[] { "-" }, StringSplitOptions.None);
int from = int.Parse(fromTo[0]);
int to = int.Parse(fromTo[1]);
for (int i = from; i <= to; i++)
{
inSet.Add(i.ToString());
}
}
else
{
inSet.Add(part);
}
}
return inSet;
}

C# "Version-Updater"

I want to increase the last number of the version (for Example: 1.0.0.0 -> 1.0.0.1).
I would prefer to kep this code :)
The actuall code looks like that:
private void UpdateApplicationVersion(string filepath)
{
string currentApplicationVersion = "1.2.3.4"
string newApplicationVersionDigit = ((currentApplicationVersion.Split('.')[3]) + 1).ToString();
string newApplicatonVersion = string.Empty;
for (int i = 0; i <= currentApplicationVersion.Length; i++)
{
if (i == 7)
{
newApplicatonVersion += newApplicationVersionDigit ;
}
else
{
newApplicatonVersion += currentApplicationVersion.ToCharArray()[i];
}
}
Do it simple way,
string v1 = "1.0.0.1";
string v2 = "1.0.0.4";
var version1 = new Version(v1);
var version2 = new Version(v2);
var result = version1.CompareTo(version2);
if (result > 0)
Console.WriteLine("version1 is greater");
else if (result < 0)
Console.WriteLine("version2 is greater");
else
Console.WriteLine("versions are equal");
I think it could be done by parsing all components of the version, manipulate the last one and put them together again as follows.
string[] Components = currentApplicationVersion.Split('.');
int Maj = Convert.ToInt32(Components[0]);
int Min = Convert.ToInt32(Components[1]);
int Revision = Convert.ToInt32(Components[2]);
int Build = Convert.ToInt32(Components[3]);
Build++;
string newApplicationVersion
= string.Format("{0}.{1}.{2}.{3}", Maj, Min, Revision, Build);
You can try Split and Join:
string currentApplicationVersion = "1.2.3.4";
int[] data = currentApplicationVersion.Split('.')
.Select(x => int.Parse(x, CultureInfo.InvariantCulture))
.ToArray();
// The last version component is data[data.Length - 1]
// so you can, say, increment it, e.g.
data[data.Length - 1] += 1;
// "1.2.3.5"
String result = String.Join(".", data);
There's a class build for working with version numbers. It's called Version and can be found in the System namespace
you can parse your current version by passing the string representing the version to the constructor
var currentApplicationVersion = new Version(currentApplicationVersionString);
and then get the new one with another of the constructors
var newApplicationVersion = new Version(
currentApplicationVersion.Major,
currentApplicationVersion.Minor,
currentApplicationVersion.Build,
currentApplicationVersion.Revision +1
);
and then simply call .ToString() if you need it as a string

Converting a boolean array into a string using c#

I have an array that looks something like:
status[0] = true
status[1] = true
status[2] = false
status[3] = true
In reality it's larger but still less than 20. I need to convert this into "ABD". Where each true represents an ordered letter in the alphabet. Can anyone think of an easy really efficient way to do this?
My napkin says this might work...
StringBuilder sb = new StringBuilder();
for(int i = 0; i < status.Length; i++)
{
if(status[i])
{
sb.Append((char)('A' + i));
}
}
string result = sb.ToString();
string input = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string result = new String(input.ToCharArray()
.Take(status.Length)
.Where((c, i) => status[i]).ToArray());
You can use Linq:
var status = new bool[] { true, true, false, true };
// alternative 1
var statusString = string.Concat(
status.Select((val, index) => val ? (char?)('A' + index) : null)
.Where(x => x != null));
// alternative 2
var statusString2 = string.Concat(
status.Select((val, index) => val ? (object)(char)('A' + index) : ""));
// alternative 3 (same as one, no boxing)
var statusString3 = string.Concat(
status.Select((val, index) => val ? (char)('A' + index) : ' ')
.Where(x => x != ' '));
// alternative 4 (no Linq, probably faster)
var statusString4 = new StringBuilder(status.Length);
for (int i = 0; i < status.Length; i++)
{
if (status[i])
statusString4.Append((char)('A' + i));
}
String[] alphabet = new String[] {"A", "B", ... "Z"};
String result = "";
for (int i = 0; i < status.Length; i++)
{
if (status[i] == true) result += alphabet[i];
}
Basically, you can create an array of the letters of the alphabet and match the true values of your status array to the corresponding letter.
Create a class like this:
class Bool2CharArrayConverter
{
public static string ConvertArray(bool[] Input)
{
int asc = 65;
StringBuilder response = StringBuilder();
foreach (bool val in Input)
{
if (val)
{
response.Append( Convert.ToChar(asc));
}
asc++;
}
return response.ToString();
}
}
which can be invoked like this:
bool[] status = new bool[]{true,true,false,true};
string output = Bool2CharArrayConverter.ConvertArray(status);
Console.WriteLine(output); //output = ABD

Categories

Resources