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
Related
Basically what I'm trying to do is take a string
string test = "hello";
and then turn it into an array as such:
string[] testing = { "h", "he", "hel", "hell", "hello" };
is this possible?
Try using Linq:
string test = "hello";
string[] testing = Enumerable
.Range(1, test.Length)
.Select(length => test.Substring(0, length))
.ToArray();
Test:
// h, he, hel, hell, hello
Console.Write(string.Join(", ", testing));
You can also do something like this:
List<string> list = new List<string>();
for(int i = 1; i <= hello.Length; i++) {
list.Add(hello.Substring(0,i));
}
Console.WriteLine(string.Join(", ", list.ToArray()));
I'd recommend Dmitry's LINQ version, but if you want a simple version that uses an array like your original question:
string input = "hello";
string[] output = new string[input.Length];
for( int i = 0; i < test.Length; ++i )
{
output[i] = test.Substring( 0, i + 1 );
}
string test = "hello";
string[] arr = new string[] {test.Substring(0,1), test.Substring(0,2), test.Substring(0,3), test.Substring(0,4), test.Substring(0,5)};
Yes, you use Linq.
string test = "hello";
List<string> lst = new List<string>();
int charCount = 1;
while (charCount <= test.Length)
{
lst.Add(string.Join("", test.Take(charCount).ToArray()));
charCount++;
}
string[] testing = lst.ToArray();
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;
}
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;
}
}
How can I find all indexes of a pattern in a string using c#?
For example I want to find all ## pattern indexes in a string like this 45##78$$#56$$JK01UU
string pattern = "##";
string sentence = "45##78$$#56$$J##K01UU";
IList<int> indeces = new List<int>();
foreach (Match match in Regex.Matches(sentence, pattern))
{
indeces.Add(match.Index);
}
indeces will have 2, 14
Edited the code to make it a cleaner function.
public IEnumerable<int> FindAllIndexes(string str, string pattern)
{
int prevIndex = -pattern.Length; // so we start at index 0
int index;
while((index = str.IndexOf(pattern, prevIndex + pattern.Length)) != -1)
{
prevIndex = index;
yield return index;
}
}
string str = "45##78$$#56$$JK01UU";
string pattern = "##";
var indexes = FindAllIndexes(str, pattern);
You can get all the indices of a pattern in a string by using a regex search like this.
string input = "45##78$$#56$$JK01UU", pattern = Regex.Escape("##");
Regex rx = new Regex(pattern);
var indices = new List<int>();
var matches = rx.Matches(s);
for (int i=0 ; i<matches.Length ; i++)
{
indices.Add(matches[i].Index);
}
Another one that tries to be efficient:
public IEnumerable<int> FindPatternIndexes(string input, string search)
{
var sb = new StringBuilder(input);
for (var i = 0; search.Length <= sb.Length; i++)
{
if (sb.ToString().StartsWith(search)) yield return i;
sb.Remove(0,1);
}
}
Tested. Worked. But somewhat dumb.
string foo = "45##78$$#56$$JK01UU";
char[] fooChar = foo.ToCharArray();
int i = 0;
bool register = false;
foreach (char fc in fooChar)
{
if (fc == '#' && register == true)
{
MessageBox.Show("Index: " + (i-1));
}
else if (fc == '#')
{
register = true;
}
else
{
register = false;
}
i++;
}
at a recent interview I attended, the programming question that was asked was this. Write a function that will take as input two strings. The output should be the result of concatenation.
Conditions: Should not use StringBuffer.Append or StringBuilder.Append or string objects for concatenation;that is, they want me to implement the pseudo code implementation of How StringBuilder or StringBuffer's Append function works.
This is what I did:
static char[] AppendStrings(string input, string append)
{
char[] inputCharArray = input.ToCharArray();
char[] appendCharArray = append.ToCharArray();
char[] outputCharArray = new char[inputCharArray.Length + appendCharArray.Length];
for (int i = 0; i < inputCharArray.Length; i++)
{
outputCharArray[i] = inputCharArray[i];
}
for (int i = 0; i < appendCharArray.Length; i++)
{
outputCharArray[input.Length + i] = appendCharArray[i];
}
return outputCharArray;
}
While this is a working solution, is there a better way of doing things?
is LINQ legal? strings are just can be treated as an enumeration of chars, so they can be used with LINQ (even though there is some cost involved, see comments):
string a = "foo";
string b = "bar";
string c = new string(a.AsEnumerable().Concat(b).ToArray());
or with your method signature:
static char[] AppendStrings(string input, string append)
{
return input.AsEnumerable().Concat(append).ToArray();
}
You can call CopyTo:
char[] output = new char[a.Length + b.Length];
a.CopyTo(0, output, 0, a.Length);
b.CopyTo(0, output, a.Length, b.Length);
return new String(output);
If they don't like that, call .ToCharArray().CopyTo(...).
You can also cheat:
return String.Join("", new [] { a, b });
return String.Format("{0}{1}", a, b);
var writer = new StringWriter();
writer.Write(a);
writer.Write(b);
return writer.ToString();
I would've done something like the following (argument checking omitted for brevity)
public static string Append(string left, string right) {
var array = new char[left.Length + right.Length];
for (var i = 0; i < left.Length; i++) {
array[i] = left[i];
}
for (var i = 0; i < right.Length; i++) {
array[i + left.Length] = right[i];
}
return new string(array);
}
In Java you can just use concat which does not use StringBuilder or StringBuffer.
String a = "foo";
String b = "bar";
String ab = a.concat(b);
The source for String.concat(String) from Oracle's JDK.
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
char buf[] = new char[count + otherLen];
getChars(0, count, buf, 0);
str.getChars(0, otherLen, buf, count);
return new String(0, count + otherLen, buf);
}
java default support "+" for append string
String temp="some text";
for(int i=0;i<10;i++)
{
temp=temp+i;
}
Or
temp=temp+" some other text"