I have done something like:
var a = "77,82,83";
foreach (var group in a.Split(','))
{
a = group.Replace("83", string.Empty);
}
If i want to remove 83 but override last updated value and got output empty or remove value from that i passed to replace.
e.g var a = 77,82,83
want output like 77,82
Edit:
"83" can be in any position.
If you want output as string you don't need to Split. Just get the LastIndexOf the , character and perform Substring on the variable:
var a = "77,82,83";
var newString = a.Substring(0, a.LastIndexOf(',')); // 77,82
If you are unsure if the string has at least one ,, you can validate before performing a Substring:
var a = "77,82,83";
var lastIndex = a.LastIndexOf(',');
if (lastIndex > 0)
var newString = a.Substring(0, lastIndex);
Update:
If you want to remove specific values from any position:
Split the string -> Remove the values using Where -> Join them with , separator
a = string.Join(",", a.Split(',').Where(i => i != "83"));
Here's a fiddle
You might need to clarify the question slightly but I think you're asking for the following:
var a = "72,82,83";
var group = a.Split(',').ToList();
int position = group.FindIndex(p => p.Contains("83"));
group.RemoveAt(position);
You can make the item you're looking for in the Contains query a parameter.
I think the problem you're having with your original code is that the foreach is a loop over each item in the array, so you're trying to remove "83" on each pass.
Related
I have a list like so:
List<string> _unWantedWords = new List<string> { "word1", "word2", "word3" };
And I have a string like so:
string input = "word1mdjw ksjcword2 d word3fjwu";
I would like to remove the unwanted words in the input string, but strings are immutable in C#, so I though I would do something fancy in one swoop with a lambda expression. Like this:
string output = _unWantedWords.Select(x => input.Replace(x, ""));
But I can't seem to get it to work, any ideas? :)
Daniel
There're subtle problems in general case with the task:
Shall we do it recursively?
"woword1rd1ABC" -> "word1ABC" -> ABC
| | | |
remove remove again
What is the order of removing? If we want to remove {"ab", "bac"} what is the desired result for "XabacY" then?
"XabacY" -> "XacY" // ab removed
-> "XaY" // bac removed
In the simplest case (remove words in order they appear in _unWantedWords, no recursion) you can put (let's use Linq since you've tried Select):
input = _unWantedWords.Aggregate(input, (s, w) => s.Replace(w, ""));
we can't change string itself, but we can change reference (i.e. assign to input)
You can use ForEach instead
_unWantedWords.ForEach(x => { input= input.Replace(x, "")});
You can use the ForEach function to replace the text in the input.
string output = input;
_unWantedWords.ForEach(x => output = output.Replace(x, ""));
You can create another variable as to not lose the original input.
This is what you need?
List < string > _unWantedWords = new List < string > {
"word1",
"word2",
"word3"
};
string input = "word1mdjw ksjcword2 d word3fjwu";
for (int i = 0; i < _unWantedWords.Count; i++) {
input = input.Replace(_unWantedWords[i], "");
}
DotNet Fiddle : https://dotnetfiddle.net/zoY4t7
Or you can simply use ForEach, read more over here
_unWantedWords.ForEach(x => {
input = input.Replace(x, "");
});
Update: July 26, 2017
I have a string inside which the values are comma separated. However for some cases it is coming double comma ,, at in a consecutive way. But when I am using using string.split(',') it's returning me a array which doesn't have a value on that index. For example
string str = "12,3,5,,6,54,127,8,,0,98,"
It's breaking down the the array this way
str2[0] = 12
str2[1] = 3
str2[2] = 5
str2[3] = ""
str2[4] = 6
str2[5] = 54
str2[6] = 127
str2[7] = 8
str2[8] = ""
str2[9] = 0
str2[10] = 98
str2[11] = ""
Look here I am getting the array with one or more empty value. So I want to put a 0 in each empty position when I am splitting the string. Here I have found something to skip the empty values
str .Split(',', StringSplitOptions.RemoveEmptyEntries)
However I did not found such a solution put a default value at empty index. I have gone through these previous Questions Q1, Q2, But these are not effective for mine. I am using C# for web application in .Net framework
Try the below code:
You can able to use IEnumerable extension method (Select) of String object.
string str = "12,3,5,,6,54,127,8,,0,98";
var strVal = str.Split(',').Select(s => string.IsNullOrWhiteSpace(s) ? "0" : s);
Use the following code to replace empty string to zero
string str = "12,3,5,,6,54,127,8,,0,98";
var a= str.Split(',').Select(x=>string.IsNullOrEmpty(x)?"0":x);
While all the suggested solutions work perfectly, they are all iterating twice your input (once for the string split, once for the string replace or regex, once for the array replace).
Here is a solution iterating only once the input:
var input = "12,3,5,,6,54,127,8,,0,98";
var result = new List<int>();
var currentNumeric = string.Empty;
foreach(char c in input)
{
if(c == ',' && String.IsNullOrWhiteSpace(currentNumeric))
{
result.Add(0);
}
else if(c == ',')
{
result.Add(int.Parse(currentNumeric));
currentNumeric = string.Empty;
}
else
{
currentNumeric += c;
}
}
if(!String.IsNullOrWhiteSpace(currentNumeric))
{
result.Add(int.Parse(currentNumeric));
}
else if(input.EndsWith(","))
{
result.Add(0);
}
You can run your string through regex to put zeros into it before going into Split:
Regex.Replace(str, "(?<=(^|,))(?=(,|$))", "0").Split(',')
The regex will insert zeros into the original string in spots when two commas are next to each other, or when a comma is detected at the beginning or at the end of the string (demo).
I would like to know if it is possible to read a certain string of n-length, from x character to y character without having to split it into smaller pieces.
I have the following string, for a path in AD CN=someName,OU=someGroup,OU=groups,DC=some,DC=domain,DC=com, and I would like to be able to just read the someName part of it, without splitting by = or , first. How do I achieve that?
Reason is, that I do not have to do group comparison as I am doing it right now:
SearchResult t1 = search.FindOne();
foreach (string s in t1.Properties["memberof"])
{
foreach (string g in groups)
{
if (s.ToLower().Contains(g.ToLower()))
{
// do something
}
}
}
I would rather make the if clause to equals, but I do not want to always split the above path/groups into an array twice. How do I do that?
Using simple string manipulation with IndexOf and Substring:
string s = "CN=someName,OU=someGroup,OU=groups,DC=some,DC=domain,DC=com";
const string prefix = "CN=";
int start = s.IndexOf(prefix);
if (start >= 0)
{
string value = s.Substring(start + prefix.Length, s.IndexOf(',', start) - prefix.Length);
Console.WriteLine(value);
}
Note that this simple example would fail if the CN= entry was the last in the line (since it’s not terminated by a comma). You could check that first by looking at the return value of the second IndexOf call though.
But in this case, CN= will usually be the first thing anyway.
If you are doing group comparisons I would use System.DirectoryServices.AccountManagement namespace
PrincipalContext Context = new PrincipalContext(ContextType.Domain, "");
UserPrincipal Usr = UserPrincipal.FindByIdentity(Context, "User");
GroupPrincipal G = GroupPrincipal.FindByIdentity(Context, "Group");
if(Usr.IsMemberOf(G)) {
}
You can use String.IndexOf to find the correct offset, then use String.SubString to read the part you want.
const string input = "CN=someName,OU=someGroup,OU=groups,DC=some,DC=domain,DC=com";
const string start = "CN=";
const string stop = ",";
int startIndex = input.IndexOf(start, 0);
int stopIndex = input.IndexOf(stop, startIndex);
var extracted = input.Substring(startIndex + start.Length, stopIndex - startIndex - start.Length);
Console.WriteLine(extracted);
.net Fiddle
PS: maybe also take a look at Is there a .NET class that can parse CN= strings out of LDAP? for your special usecase!
With Split you can check if any of the given keys equals to the search value.
var val = "CN=someName,OU=someGroup,OU=groups,DC=some,DC=domain,DC=com";
var prefix = "CN";
var searchValue = "someName";
var contains = val.Split(',').Any(value => value.Split('=')[0] == prefix && value.Split('=')[1] == searchValue);
Insead of checking if the value is equal to the search value you can also just return the value.
var val = "CN=someName,OU=someGroup,OU=groups,DC=some,DC=domain,DC=com";
var prefix = "CN";
var foundValue = val.Split(',').FirstOrDefault(value => value.Split('=')[0] == prefix)?.Split('=')[1];
I still used Split despite you said you don't want to use it as I think it makes a nice one liner.
I have this code:
string firstTag = "Forums2008/forumPage.aspx?forumId=";
string endTag = "</a>";
index = forums.IndexOf(firstTag, index1);
if (index == -1)
continue;
var secondIndex = forums.IndexOf(endTag, index);
result = forums.Substring(index + firstTag.Length + 12, secondIndex - (index + firstTag.Length - 50));
The string i want to extract from is for example:
הנקה
What i want to get is the word after the title only this: הנקה
And the second problem is that when i'm extracting it i see instead hebrew some gibrish like this: ������
One powerful way to do this is to use Regular Expressions instead of trying to find a starting position and use a substring. Try out this code, and you'll see that it extracts the anchor tag's title:
var input = "הנקה";
var expression = new System.Text.RegularExpressions.Regex(#"title=\""([^\""]+)\""");
var match = expression.Match(input);
if (match.Success) {
Console.WriteLine(match.Groups[1]);
}
else {
Console.WriteLine("not found");
}
And for the curious, here is a version in JavaScript:
var input = 'הנקה';
var expression = new RegExp('title=\"([^\"]+)\"');
var results = expression.exec(input);
if (results) {
document.write(results[1]);
}
else {
document.write("not found");
}
Okay here is the solution using String.Substring() String.Split() and String.IndexOf()
String str = "הנקה"; // <== Assume this is passing string. Yes unusual scape sequence are added
int splitStart = str.IndexOf("title="); // < Where to start splitting
int splitEnd = str.LastIndexOf("</a>"); // < = Where to end
/* What we try to extract is this : title="הנקה">הנקה
* (Given without escape sequence)
*/
String extracted = str.Substring(splitStart, splitEnd - splitStart); // <=Extracting required portion
String[] splitted = extracted.Split('"'); // < = Now split with "
Console.WriteLine(splitted[1]); // <= Try to Out but yes will produce ???? But put a breakpoint here and check the values in split array
Now the problem, here you can see that i have to use escape sequence in an unusual way. You may ignore that since you are simply passing the scanning string.
And this actually works, but you cannot visualize it with the provided Console.WriteLine(splitted[1]);
But if you put a break point and check the extracted split array you can see that text are extracted. you can confirm it with following screenshot
I have a text file whose format is like this
Number,Name,Age
I want to read "Number" at the first column of this text file into an array to find duplication. here is the two ways i tried to read in the file.
string[] account = File.ReadAllLines(path);
string readtext = File.ReadAllText(path);
But every time i try to split the array to just get whats to the left of the first comma i fail. Have any ideas? Thanks.
You need to explicitly split the data to access its various parts. How would your program otherwise be able to decide that it is separated by commas?
The easiest approach to access the number that comes to my mind goes something like this:
var lines = File.ReadAllLines(path);
var firstLine = lines[0];
var fields = firstLine.Split(',');
var number = fields[0]; // Voilla!
You could go further by parsing the number as an int or another numeric type (if it really is a number). On the other hand, if you just want to test for uniqueness, this is not really necessary.
If you want all duplicate lines according to the Number:
var numDuplicates = File.ReadLines(path)
.Select(l => l.Trim().Split(','))
.Where(arr => arr.Length >= 3)
.Select(arr => new {
Number = arr[0].Trim(),
Name = arr[1].Trim(),
Age = arr[2].Trim()
})
.GroupBy(x => x.Number)
.Where(g => g.Count() > 1);
foreach(var dupNumGroup in numDuplicates)
Console.WriteLine("Number:{0} Names:{1} Ages:{2}"
, dupNumGroup.Key
, string.Join(",", dupNumGroup.Select(x => x.Name))
, string.Join(",", dupNumGroup.Select(x => x.Age)));
If you are looking specifically for a string.split solution, here is a really simple method of doing what you are looking for:
List<int> importedNumbers = new List<int>();
// Read our file in to an array of strings
var fileContents = System.IO.File.ReadAllLines(path);
// Iterate over the strings and split them in to their respective columns
foreach (string line in fileContents)
{
var fields = line.Split(',');
if (fields.Count() < 3)
throw new Exception("We need at least 3 fields per line."); // You would REALLY do something else here...
// You would probably want to be more careful about your int parsing... (use TryParse)
var number = int.Parse(fields[0]);
var name = fields[1];
var age = int.Parse(fields[2]);
// if we already imported this number, continue on to the next record
if (importedNumbers.Contains(number))
continue; // You might also update the existing record at this point instead of just skipping...
importedNumbers.Add(number); // Keep track of numbers we have imported
}