Using Substring to find occurrence number - c#

I am reading a file in C#. I want to check value from a string. The line consists as following:
20 EMP HAPPENS 5 TIMES.
40 SUP HAPPENS 7 TIMES.
I want to find the number of times. I have written the following code:
if(line.IndexOf(HAPPENS) + 1 > 0)
arrayLength= int.Parse(line.Substring(line.IndexOf(HAPPENED) + OCCURS.Length + 1).Trim("."));
But exception is thrown.
What is the efficient way to do that?

Substring method takes two params, see declaration:
public string Substring(int startIndex,int length)

Here some psuedo code to get your count:
//read lines from file
foreach (string line in lines){
if (line.Contains("HAPPENS")){
int happensindex = line.IndexOf("HAPPENS");
int timesindex = line.IndexOf("TIMES");
int happenscount;
int indexCount = happensindex + 8;
int countLength = happensindex - timesindex - 9;
if (int.TryParse(line.Substring(indexCount , countLength), out happenscount){
//happenscount contains your count
}
}
}

You can use this LINQ query to real the lines of the file and extract the informations:
var allOccurrences = File.ReadLines("Path")
.Select(l => new { HappenIndex = l.IndexOf(" HAPPENS "), Line = l })
.Where(LineInfo => LineInfo.HappenIndex >= 0)
.Select(LineInfo =>
{
var retVal = new { LineInfo, What = LineInfo.Line.Substring(0, LineInfo.HappenIndex).Trim(), Occurences = (int?)null };
int timesIndex = LineInfo.Line.IndexOf(" TIMES", LineInfo.HappenIndex + " HAPPENS ".Length);
if(timesIndex >= 0)
{
int behindHappen = LineInfo.HappenIndex + " HAPPENS ".Length;
string times = LineInfo.Line.Substring(behindHappen, timesIndex - behindHappen).Trim();
int occurences;
if(int.TryParse(times, out occurences))
retVal = new { LineInfo, retVal.What, Occurences = (int?)occurences };
}
return retVal;
})
.Where(x => x.Occurences.HasValue)
.ToList();
foreach (var occ in allOccurrences)
{
Console.WriteLine("Line contains '{0}' {1} times", occ.What, occ.Occurences);
}

Related

How to split string with date in c#

i have string with date , i want to split it with date and string
For example :
I have this type of strings data
9/23/2013/marking abandoned based on notes below/DB
12/8/2012/I think the thid is string/SG
and i want to make it like as
9/23/2013 marking abandoned based on notes below/DB
12/8/2013 I think the thid is string/SG
so, i don't know how to split these strings and store in different columns of table.
pls help me.
string[] vals = { "9/23/2013/marking abandoned based on notes below/DB",
"12/8/2012/I think the thid is string/SG" };
var regex = #"(\d{1,2}/\d{1,2}/\d{4})/(.*)";
var matches = vals.Select(val => Regex.Match(vals, regex));
foreach (var match in matches)
{
Console.WriteLine ("{0} {1}", match.Groups[1], match.Groups[2]);
}
prints:
9/23/2013 marking abandoned based on notes below/DB
12/8/2012 I think the thid is string/SG
(\d{1,2}/\d{1,2}/\d{4})/(.*) breaks down to
(\d{1,2}/\d{1,2}/\d{4}):
\d{1,2} - matches any one or two digit number
/ - matches to one / symbol
\d{4} - matches to four digit number
(...) - denotes first group
(.*) - matches everything else and creates second group
Another way to do it with LINQ:
var inputs = new[]{
"9/23/2013/marking abandoned based on notes below/DB",
"12/8/2012/I think the thid is string/SG"
};
foreach (var item in inputs)
{
int counter = 0;
var r = item.Split('/')
.Aggregate("", (a, b) =>
a + ((counter++ == 3) ? "\t" : ((counter == 1) ? "" : "/")) + b);
Console.WriteLine(r);
}
Or you may use the IndexOf and Substring methods:
foreach (var item in inputs)
{
var lastPos =
item.IndexOf('/',
1 + item.IndexOf('/',
1 + item.IndexOf('/')));
if (lastPos != -1)
{
var r = String.Join("\t",
item.Substring(0, lastPos),
item.Substring(lastPos + 1, item.Length - lastPos - 1));
Console.WriteLine(r);
}
}
Perhaps with pure string methods, the third slash separates the date and the text:
string line = "9/23/2013/marking abandoned based on notes below/DB";
int slashIndex = line.IndexOf('/');
if(slashIndex >= 0)
{
int slashCount = 1;
while(slashCount < 3 && slashIndex >= 0)
{
slashIndex = line.IndexOf('/', slashIndex + 1);
if(slashIndex >= 0) slashCount++;
}
if(slashCount == 3)
{
Console.WriteLine("Date:{0} Text: {1}"
, line.Substring(0, slashIndex)
, line.Substring(slashIndex +1));
}
}
For what it's worth, here is a extension method to "break" a string in half on nth occurence of astring:
public static class StringExtensions
{
public static string[] BreakOnNthIndexOf(this string input, string value, int breakOn, StringComparison comparison)
{
if (breakOn <= 0)
throw new ArgumentException("breakOn must be greater than 0", "breakOn");
if (value == null) value = " "; // fallback on white-space
int slashIndex = input.IndexOf(value, comparison);
if (slashIndex >= 0)
{
int slashCount = 1;
while (slashCount < breakOn && slashIndex >= 0)
{
slashIndex = input.IndexOf(value, slashIndex + value.Length, comparison);
if (slashIndex >= 0) slashCount++;
}
if (slashCount == breakOn)
{
return new[] {
input.Substring(0, slashIndex),
input.Substring(slashIndex + value.Length)
};
}
}
return new[]{ input };
}
}
Use it in this way:
string line1 = "9/23/2013/marking abandoned based on notes below/DB";
string line2 = "12/8/2012/I think the thid is string/SG";
string[] res1 = line1.BreakOnNthIndexOf("/", 3, StringComparison.OrdinalIgnoreCase);
string[] res2 = line2.BreakOnNthIndexOf("/", 3, StringComparison.OrdinalIgnoreCase);

Add separator to string at every N characters?

I have a string which contains binary digits. How to separate string after each 8 digit?
Suppose the string is:
string x = "111111110000000011111111000000001111111100000000";
I want to add a separator like ,(comma) after each 8 character.
output should be :
"11111111,00000000,11111111,00000000,11111111,00000000,"
Then I want to send it to a list<> last 8 char 1st then the previous 8 chars(excepting ,) and so on.
How can I do this?
Regex.Replace(myString, ".{8}", "$0,");
If you want an array of eight-character strings, then the following is probably easier:
Regex.Split(myString, "(?<=^(.{8})+)");
which will split the string only at points where a multiple of eight characters precede it.
Try this:
var s = "111111110000000011111111000000001111111100000000";
var list = Enumerable
.Range(0, s.Length/8)
.Select(i => s.Substring(i*8, 8));
var res = string.Join(",", list);
There's another Regex approach:
var str = "111111110000000011111111000000001111111100000000";
# for .NET 4
var res = String.Join(",",Regex.Matches(str, #"\d{8}").Cast<Match>());
# for .NET 3.5
var res = String.Join(",", Regex.Matches(str, #"\d{8}")
.OfType<Match>()
.Select(m => m.Value).ToArray());
...or old school:
public static List<string> splitter(string in, out string csv)
{
if (in.length % 8 != 0) throw new ArgumentException("in");
var lst = new List<string>(in/8);
for (int i=0; i < in.length / 8; i++) lst.Add(in.Substring(i*8,8));
csv = string.Join(",", lst); //This we want in input order (I believe)
lst.Reverse(); //As we want list in reverse order (I believe)
return lst;
}
Ugly but less garbage:
private string InsertStrings(string s, int insertEvery, char insert)
{
char[] ins = s.ToCharArray();
int length = s.Length + (s.Length / insertEvery);
if (ins.Length % insertEvery == 0)
{
length--;
}
var outs = new char[length];
long di = 0;
long si = 0;
while (si < s.Length - insertEvery)
{
Array.Copy(ins, si, outs, di, insertEvery);
si += insertEvery;
di += insertEvery;
outs[di] = insert;
di ++;
}
Array.Copy(ins, si, outs, di, ins.Length - si);
return new string(outs);
}
String overload:
private string InsertStrings(string s, int insertEvery, string insert)
{
char[] ins = s.ToCharArray();
char[] inserts = insert.ToCharArray();
int insertLength = inserts.Length;
int length = s.Length + (s.Length / insertEvery) * insert.Length;
if (ins.Length % insertEvery == 0)
{
length -= insert.Length;
}
var outs = new char[length];
long di = 0;
long si = 0;
while (si < s.Length - insertEvery)
{
Array.Copy(ins, si, outs, di, insertEvery);
si += insertEvery;
di += insertEvery;
Array.Copy(inserts, 0, outs, di, insertLength);
di += insertLength;
}
Array.Copy(ins, si, outs, di, ins.Length - si);
return new string(outs);
}
If I understand your last requirement correctly (it's not clear to me if you need the intermediate comma-delimited string or not), you could do this:
var enumerable = "111111110000000011111111000000001111111100000000".Batch(8).Reverse();
By utilizing morelinq.
Here my two little cents too. An implementation using StringBuilder:
public static string AddChunkSeparator (string str, int chunk_len, char separator)
{
if (str == null || str.Length < chunk_len) {
return str;
}
StringBuilder builder = new StringBuilder();
for (var index = 0; index < str.Length; index += chunk_len) {
builder.Append(str, index, chunk_len);
builder.Append(separator);
}
return builder.ToString();
}
You can call it like this:
string data = "111111110000000011111111000000001111111100000000";
string output = AddChunkSeparator(data, 8, ',');
One way using LINQ:
string data = "111111110000000011111111000000001111111100000000";
const int separateOnLength = 8;
string separated = new string(
data.Select((x,i) => i > 0 && i % separateOnLength == 0 ? new [] { ',', x } : new [] { x })
.SelectMany(x => x)
.ToArray()
);
I did it using Pattern & Matcher as following way:
fun addAnyCharacter(input: String, insertion: String, interval: Int): String {
val pattern = Pattern.compile("(.{$interval})", Pattern.DOTALL)
val matcher = pattern.matcher(input)
return matcher.replaceAll("$1$insertion")
}
Where:
input indicates Input string. Check results section.
insertion indicates Insert string between those characters. For example comma (,), start(*), hash(#).
interval indicates at which interval you want to add insertion character.
input indicates Input string. Check results section. Check results section; here I've added insertion at every 4th character.
Results:
I/P: 1234XXXXXXXX5678 O/P: 1234 XXXX XXXX 5678
I/P: 1234567812345678 O/P: 1234 5678 1234 5678
I/P: ABCDEFGHIJKLMNOP O/P: ABCD EFGH IJKL MNOP
Hope this helps.
As of .Net 6, you can simply use the IEnumerable.Chunk method (Which splits elements of a sequence into chunks) then reconcatenate the chunks using String.Join.
var text = "...";
string.Join(',', text.Chunk(size: 6).Select(x => new string(x)));
This is much faster without copying array (this version inserts space every 3 digits but you can adjust it to your needs)
public string GetString(double valueField)
{
char[] ins = valueField.ToString().ToCharArray();
int length = ins.Length + (ins.Length / 3);
if (ins.Length % 3 == 0)
{
length--;
}
char[] outs = new char[length];
int i = length - 1;
int j = ins.Length - 1;
int k = 0;
do
{
if (k == 3)
{
outs[i--] = ' ';
k = 0;
}
else
{
outs[i--] = ins[j--];
k++;
}
}
while (i >= 0);
return new string(outs);
}
For every 1 character, you could do this one-liner:
string.Join(".", "1234".ToArray()) //result: 1.2.3.4
If you intend to create your own function to acheive this without using regex or pattern matching methods, you can create a simple function like this:
String formatString(String key, String seperator, int afterEvery){
String formattedKey = "";
for(int i=0; i<key.length(); i++){
formattedKey += key.substring(i,i+1);
if((i+1)%afterEvery==0)
formattedKey += seperator;
}
if(formattedKey.endsWith("-"))
formattedKey = formattedKey.substring(0,formattedKey.length()-1);
return formattedKey;
}
Calling the mothod like this
formatString("ABCDEFGHIJKLMNOPQRST", "-", 4)
Would result in the return string as this
ABCD-EFGH-IJKL-MNOP-QRST
A little late to the party, but here's a simplified LINQ expression to break an input string x into groups of n separated by another string sep:
string sep = ",";
int n = 8;
string result = String.Join(sep, x.InSetsOf(n).Select(g => new String(g.ToArray())));
A quick rundown of what's happening here:
x is being treated as an IEnumerable<char>, which is where the InSetsOf extension method comes in.
InSetsOf(n) groups characters into an IEnumerable of IEnumerable -- each entry in the outer grouping contains an inner group of n characters.
Inside the Select method, each group of n characters is turned back into a string by using the String() constructor that takes an array of chars.
The result of Select is now an IEnumerable<string>, which is passed into String.Join to interleave the sep string, just like any other example.
I am more than late with my answer but you can use this one:
static string PutLineBreak(string str, int split)
{
for (int a = 1; a <= str.Length; a++)
{
if (a % split == 0)
str = str.Insert(a, "\n");
}
return str;
}

C# line break every n characters

Suppose I have a string with the text: "THIS IS A TEST". How would I split it every n characters? So if n was 10, then it would display:
"THIS IS A "
"TEST"
..you get the idea. The reason is because I want to split a very big line into smaller lines, sort of like word wrap. I think I can use string.Split() for this, but I have no idea how and I'm confused.
Any help would be appreciated.
Let's borrow an implementation from my answer on code review. This inserts a line break every n characters:
public static string SpliceText(string text, int lineLength) {
return Regex.Replace(text, "(.{" + lineLength + "})", "$1" + Environment.NewLine);
}
Edit:
To return an array of strings instead:
public static string[] SpliceText(string text, int lineLength) {
return Regex.Matches(text, ".{1," + lineLength + "}").Cast<Match>().Select(m => m.Value).ToArray();
}
Maybe this can be used to handle efficiently extreme large files :
public IEnumerable<string> GetChunks(this string sourceString, int chunkLength)
{
using(var sr = new StringReader(sourceString))
{
var buffer = new char[chunkLength];
int read;
while((read= sr.Read(buffer, 0, chunkLength)) == chunkLength)
{
yield return new string(buffer, 0, read);
}
}
}
Actually, this works for any TextReader. StreamReader is the most common used TextReader. You can handle very large text files (IIS Log files, SharePoint Log files, etc) without having to load the whole file, but reading it line by line.
You should be able to use a regex for this. Here is an example:
//in this case n = 10 - adjust as needed
List<string> groups = (from Match m in Regex.Matches(str, ".{1,10}")
select m.Value).ToList();
string newString = String.Join(Environment.NewLine, lst.ToArray());
Refer to this question for details:
Splitting a string into chunks of a certain size
Probably not the most optimal way, but without regex:
string test = "my awesome line of text which will be split every n characters";
int nInterval = 10;
string res = String.Concat(test.Select((c, i) => i > 0 && (i % nInterval) == 0 ? c.ToString() + Environment.NewLine : c.ToString()));
Coming back to this after doing a code review, there's another way of doing the same without using Regex
public static IEnumerable<string> SplitText(string text, int length)
{
for (int i = 0; i < text.Length; i += length)
{
yield return text.Substring(i, Math.Min(length, text.Length - i));
}
}
Some code that I just wrote:
string[] SplitByLength(string line, int len, int IsB64=0) {
int i;
if (IsB64 == 1) {
// Only Allow Base64 Line Lengths without '=' padding
int mod64 = (len % 4);
if (mod64 != 0) {
len = len + (4 - mod64);
}
}
int parts = line.Length / len;
int frac = line.Length % len;
int extra = 0;
if (frac != 0) {
extra = 1;
}
string[] oline = new string[parts + extra];
for(i=0; i < parts; i++) {
oline[i] = line.Substring(0, len);
line = line.Substring(len);
}
if (extra == 1) {
oline[i] = line;
}
return oline;
}
string CRSplitByLength(string line, int len, int IsB64 = 0)
{
string[] lines = SplitByLength(line, len, IsB64);
return string.Join(System.Environment.NewLine, lines);
}
string m = "1234567890abcdefghijklmnopqrstuvwxhyz";
string[] r = SplitByLength(m, 6, 0);
foreach (string item in r) {
Console.WriteLine("{0}", item);
}

C# third index of a character in a string

is there a command that can get the third index of a character in a string? For example:
error: file.ext: line 10: invalid command [test:)]
In the above sentence, I want to the index of the 3rd colon, the one next to the 10. How could I do that? I know of string.IndexOf and string.LastIndexOf, but in this case I want to get the index of a character when it is used the third time.
String.IndexOf will get you the index of the first, but has overloads giving a starting point. So you can use a the result of the first IndexOf plus one as the starting point for the next. And then just accumulate indexes a sufficient number of times:
var offset = myString.IndexOf(':');
offset = myString.IndexOf(':', offset+1);
var result = myString.IndexOf(':', offset+1);
Add error handling unless you know that myString contains at least three colons.
You could write something like:
public static int CustomIndexOf(this string source, char toFind, int position)
{
int index = -1;
for (int i = 0; i < position; i++)
{
index = source.IndexOf(toFind, index + 1);
if (index == -1)
break;
}
return index;
}
EDIT: Obviously you have to use it as follows:
int colonPosition = myString.CustomIndexOf(',', 3);
I am guessing you want to parse that string into different parts.
public static void Main() {
var input = #"error: file.ext: line 10: invalid command [test (: ]";
var splitted = input .Split(separator: new[] {": "}, count: 4, options: StringSplitOptions.None);
var severity = splitted[0]; // "error"
var filename = splitted[1]; // "file.ext"
var line = splitted[2]; // "line 10"
var message = splitted[3]; // "invalid command [test (: ]"
}
This has already been answered several very good ways - but I decided to try and write it using Expressions.
private int? GetNthOccurrance(string inputString, char charToFind, int occurranceToFind)
{
int totalOccurrances = inputString.ToCharArray().Count(c => c == charToFind);
if (totalOccurrances < occurranceToFind || occurranceToFind <= 0)
{
return null;
}
var charIndex =
Enumerable.Range(0, inputString.Length - 1)
.Select(r => new { Position = r, Char = inputString[r], Count = 1 })
.Where(r => r.Char == charToFind);
return charIndex
.Select(c => new
{
c.Position,
c.Char,
Count = charIndex.Count(c2 => c2.Position <= c.Position)
})
.Where(r => r.Count == occurranceToFind)
.Select(r => r.Position)
.First();
}
and Tests to prove it too:
Assert.AreEqual(0, GetNthOccurrance(input, 'h', 1));
Assert.AreEqual(3, GetNthOccurrance(input, 'l', 2));
Assert.IsNull(GetNthOccurrance(input, 'z', 1));
Assert.IsNull(GetNthOccurrance(input, 'h', 10));
You can call .IndexOf(char, position) to search from desired position, thus you should call it 3 times (but, after each call you should also check if something is found).
int pos = -1;
for ( int k = 0; k < 3; ++k )
{
pos = s.indexOf( ':', pos+1 );
// Check if pos < 0...
}
A little ugly, but an alternative approach (to the others already posted) that works:
public int FindThirdColonIndex(string msg)
{
for (int i = 0, colonCount = 0; i < msg.Length; i++)
{
if (msg[i] == ':' && ++colonCount == 3) { return i; }
}
// Not found
return -1;
}
Here is a recursive implementation (for string not char) - as an extension method, mimicing the format of the framework method(s).
All you need to do is change 'string value' to 'char value' in the extension method and update the tests accordingly and it will work... I'm happy to do that and post it if anyone is interested?
public static int IndexOfNth(
this string input, string value, int startIndex, int nth)
{
if (nth < 1)
throw new NotSupportedException("Param 'nth' must be greater than 0!");
if (nth == 1)
input.IndexOf(value, startIndex);
return
input.IndexOfNth(value, input.IndexOf(value, startIndex) + 1, --nth);
}
Also, here are some (MBUnit) unit tests that might help you (to prove it is correct):
[Test]
public void TestIndexOfNthWorksForNth1()
{
const string input = "foo<br />bar<br />baz<br />";
Assert.AreEqual(3, input.IndexOfNth("<br />", 0, 1));
}
[Test]
public void TestIndexOfNthWorksForNth2()
{
const string input = "foo<br />whatthedeuce<br />kthxbai<br />";
Assert.AreEqual(21, input.IndexOfNth("<br />", 0, 2));
}
[Test]
public void TestIndexOfNthWorksForNth3()
{
const string input = "foo<br />whatthedeuce<br />kthxbai<br />";
Assert.AreEqual(34, input.IndexOfNth("<br />", 0, 3));
}
Please see this answer on a similar question:
https://stackoverflow.com/a/46460083/7673306
It provides a method for you to find the index of nth occurrence of a specific character within a designated string.
In your specific case it would be implemented like so:
int index = IndexOfNthCharacter("error: file.ext: line 10: invalid command [test:)]", 3, ':');
Simply split the string by the char.
This gives you an array that you can then use to target what you want.
var stringToSplit = "one_two_three_four";
var splitString = stringToSplit.Split("_");
if (splitString.length > 3){
var newString = $"{splitResult[0]}_{splitResult[1]}_{splitResult[2]}";
}

How to get continuous characters in C#?

I've a
List<String> MyList=new List<string>();
I need to fill the list MyList with n values.
if the value of n is 2 then the list MyList will contain
"A","B"
if 10 then
"A","B","C"....."J"
if 30 then
"A"....."Z","AA","AB",AC","AD"
if 1000 then
"A",....."Z","AA","AB"......"AZ","BA","BB"......."BZ"........"YZ","AAA",AAB".....
and so on
I do not know how to do this.
Please help me to do this using any method Using LINQ or LAMBDA Expression
Edit 2:
This is probably the easiest way to implement it. I tested it, it works fine. You could generate a infinite number of strings.
public IEnumerable<string> GenerateStrings()
{
foreach(string character in Alphabet())
{
yield return character;
}
foreach (string prefix in GenerateStrings())
{
foreach(string suffix in Alphabet())
{
yield return prefix + suffix;
}
}
}
public IEnumerable<string> Alphabet()
{
for(int i = 0; i < 26; i++)
{
yield return ((char)('A' + i)).ToString();
}
}
Stuff I wrote before:
You could also write a little recursive function which returns any string by a certain index. This may not be optimal performance wise, because there are some repetitive divisions, but it may be fast enough for your purpose.
It is quite short and easy:
string GetString(int index)
{
if (index < 26)
{
return ((char)('A' + index)).ToString();
}
return GetString(index / 26 - 1) + GetString(index % 26);
}
usage (may also be put into another method:
List<string> strings = Enumerable.Range(0, 1000)
.Select(x => GetString(x))
.ToList();
This is working code, just wrote a test for it.
Edit: eg, the "full linq way" application of GetString:
public void IEnumerale<string> GenerateStrings()
{
int index = 0;
// generate "infinit" number of values ...
while (true)
{
// ignoring index == int.MaxValue
yield return GetString(index++);
}
}
List<string> strings = GenerateStrings().Take(1000).ToList();
I did something similar in SQL a while back.
Translated to C# this is a function to create a code from a number:
public static string GetCode(int id) {
string code, chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (id <= chars.Length) {
code = chars.Substring(id - 1, 1);
} else {
id--;
int value = chars.Length, adder = 0;
while (id >= value * (chars.Length + 1) + adder) {
adder += value;
value *= chars.Length;
}
code = chars.Substring((id - adder) / value - 1, 1);
id = ((id - adder) % value);
while (value > 1) {
value /= chars.Length;
code += chars.Substring(id / value, 1);
id = id % value;
}
}
return code;
}
Then you just get numbers from 1 and up, and translate into codes:
var codes = Enumerable.Range(1, 1000).Select(n => GetCode(n));
The limit of the function is currently "ZZZZZZ" or 321272406. (After that you get a division by zero.)
Note that this function uses all combinations and returns "A".."Z", "AA".."ZZ", "AAA"..."ZZZ" rather than starting at "AB" and "ABC".
This is similar to this question (but not quite enough to mark it as a duplicate, and it's a hard problem to search for anyway).
Use any of the working IEnumerable<string> answers (or at least, any which cover the range you need), and then if you need to create a list with a certain number of elements, just use:
List<string> list = GenerateSequence().Take(count).ToList();
This code is working fine, but I'm not sure if it's "LINQ enough".
char[] validChars = Enumerable.Range(0, 26).Select(i => (char)('A' + i)).ToArray();
List<string> result = new List<string>();
List<string> generator = validChars.Select(ch => ch.ToString()).ToList();
int n = 1000;
while (result.Count < n)
{
result.AddRange(generator);
generator = generator.Take((n - result.Count) / validChars.Length + 1)
.SelectMany(s => validChars.Select(ch => s + ch))
.ToList();
}
var output = result.Take(n);
Try the below .. I am using Cross Join and a Union to build the source and then filtering the record by using the Take extension method
char[] charArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
List<String> MyList = new List<string>();
int n = 1000;
(from value1 in charArray
select new
{
newString = value1.ToString()
})
.Union
(
(from value1 in charArray
from value2 in charArray
select new
{
newString = string.Concat(value1, value2)
})
)
.Union
(
(from value1 in charArray
from value2 in charArray
from value3 in charArray
select new
{
newString = string.Concat(value1, value2, value3)
})
)
.Take(n)
.ToList()
.ForEach(i => MyList.Add(i.newString));
Hope this will give you some idea of using a combination of Linq,Lambda and Extension method.
#DannyChen this is it. your code with a little changes..
char[] validChars = Enumerable.Range(0, 26).Select(i => (char)('A' + i)).ToArray();
int n = 30;
int pointer = 0;
int pointerSec = 0;
int Deg = 0;
string prefix = string.Empty;
string prefixMore = string.Empty;
List<string> result = new List<string>();
while (n > 0)
{
result.AddRange(validChars.Skip(pointer).Select(ch => prefix + ch).Take(n));
if (pointer == 26)
{
pointer = -1;
Deg += 1;
prefixMore = "" + validChars[pointerSec];
pointerSec++;
n++;
}
else
{
if (Deg == 0)
{
prefix = "" + validChars[pointer];
}
else
{
prefix = prefixMore + validChars[pointer];
}
}
n--;
pointer++;
}
it is 100% correct.

Categories

Resources