IEnumerable<string> function c# .net - c#

i have faced this question in interview as below?
let us consider the string named
string gowtham="test1,test2,test3" ;
i need to convert in to IEnumerable string function
i need a output to be as
new[] {"test1", "test2","test3" }
what i did is i have created a string() function by spliting values by comma seperated as below
string[] mysamples= gowtham.Split(',');
i do not know how to proceed after
waiting for your responses?

Every array is already a IEnumerable, in your case if you want to explicit cast to one IEnumerable of string you could use
IEnumerable<string> mysamplesEnumerable = mysamples as IEnumerable<string>
if you interviewer wanted a function that did this you could do
IEnumerable<string> SplitEnumByComa(string input)
{
return input.Split(',');
}

If I understand your question clearly, you can use a method like this;
public static IEnumerable<string> YourMethod()
{
string gowtham = "test1,test2,test3";
string[] mysamples = gowtham.Split(',');
List<string> senum = new List<string>();
foreach ( string s in mysamples )
{
senum.Add(s);
}
return senum as IEnumerable<string>;
}
Since string[] implements IEnumerable<T> interface, it seems you just need to cast it as IEnumerable<T>
EDIT: Since Magnus and LukeH warned me, there is an easy way also what you want to do.
public static IEnumerable<string> YourMethod()
{
string gowtham = "test1,test2,test3";
return gowtham .Split(',');
}

Related

C# Linq Expression to remove from string if found in an array

I have a simple function that loops through a static string array and tests to see if a string contains any instance of the array. If true, then the text from the string is removed (replaced with an empty string).
This function works, but I need to create a LINQ expression to do this (or a one-line expression). I can't figure out how to do this unless I turn my string s into an array. But if I do that then it complicates trying to match the facilities strings. How can I accomplish this in a one-liner?
private static string[] facilities = { "MX10", "MX80", "MX81", "MX82", "MX83", "US00", "US10", "US11", "US20", "US30", "US50", "US60", "US70", "US99" };
private static string cleansePN(string s)
{
for (int i = 0; i < facilities.Length; i++)
{
s = s.Replace(facilities[i], string.Empty);
}
return s;
}
Linq Aggregate:
private static string cleansePN(string s)
{
return facilities.Aggregate(s, (current, t) => current.Replace(t, string.Empty));
}

c# if contains AND/OR

Is there a variant of this?
if (blabla.Contains("I'm a noob") | blabla.Contains("sry") | blabla.Contains("I'm a noob "+"sry"))
{
//stuff
}
like:
if (blabla.Contains("I'm a noob) and/or ("sry")
{
//stuff
}
Help is appreciated!
You can't collapse it quite as far as you asked, but you can do:
if (blabla.Contains("I'm a noob") || blabla.Contains("sry"))
{
//stuff
}
The "and" case is handled here because a string with both would actually pass both of the statements in the "Or".
As far as I'm aware, there are no built-in methods to do this. But with a little LINQ and extension methods, you can create your own methods that will check to see if a string contains any or all tokens:
public static class ExtensionMethods{
public static bool ContainsAny(this string s, params string[] tokens){
return tokens.Any(t => s.Contains(t));
}
public static bool ContainsAll(this string s, params string[] tokens){
return tokens.All(t => s.Contains(t));
}
}
You could use it like this (remember, params arrays take a variable number of parameters, so you're not limited to just two like in my example):
var str = "this is a string";
Console.WriteLine(str.ContainsAny("this", "fake"));
Console.WriteLine(str.ContainsAny("doesn't", "exist"));
Console.WriteLine(str.ContainsAll("this", "is"));
Console.WriteLine(str.ContainsAll("this", "fake"));
Output:
True
False
True
False
Edit:
For the record, LINQ is not necessary. You could just as easily write them this way:
public static class ExtensionMethods{
public static bool ContainsAny(this string s, params string[] tokens){
foreach(string token in tokens)
if(s.Contains(token)) return true;
return false;
}
public static bool ContainsAll(this string s, params string[] tokens){
foreach(string token in tokens)
if(!s.Contains(token)) return false;
return true;
}
}
var arr = new[]{"I'm a noob" ,"sry", "I'm a noob +sry"};
if(arr.Any(x => blabla.Contains(x)))
{
}
You can use a regex:
Regex r = new Regex("I'm a noob|sry|I'm a noob sry");
if(r.IsMatch(blabla)) {
//TODO: do something
}
Regular expressions have other advanced features like: a* matches with the empty string, a, aa, aaa,...
The funny part is that if you "compile" the regex (for instance using new Regex("I'm a noob|sry|I'm a noob sry",RegexOptions.Compiled), C# will turn it automatically into the fastest solution mechanism possible. For instance if blabla is a 100k chars string, you will only run once over the entire string. And for instance redundant parts like I'm a noob sry will be omitted automatically.

Check string for an array item and match it

I have a string and an array and i want to check the string and find if the string contains any string from the array.
My array will contain about 10 elements max.
string[] stringArray = { "apple", "banana", "orange" };
string text="I want an apple";
public static string getItem(string text)
{
//check text for stringArray items
//return item (apple, banana, orange)
}
string item = getItem(text);
So what im looking for is to create a method that returns the item from. Also i'd like to know if there any alternatives ways to do this with Enum or List<>.
Finally i made my method like this
public static string getItem(string text)
{
string[] stringArray = { "Apple", "Banana", "Orange" };
string item = stringArray.Where(s => text.ToUpper().Contains(s)).DefaultIfEmpty("None").FirstOrDefault();;
return item;
}
With just a bit of LINQ-iness, this because quite easy:
return stringArray.Where(s => text.Contains(s)).FirstOrDefault();
This assumes that you want to return only the first matched string and that you want to do a case-sensitive comparison. If not, minor modifications can be made relatively easily to change things.
The code above will also work equally as well if your source is a List<string> as well (actually, anything that implements IEnumerable<string> will work in its place). An Enum, on the other hand, is not the proper fit for this kind of thing.
Instead of your array, you can make it a List<string>. And then in your getItem(), you can do:
List<string> stringList; // populate how you see fit
string text="I want an apple";
public static string getItem(string text)
{
foreach(var s in stringList)
{
if(text.Contains(s))
{
// do stuff here
}
}
}
A List<> isn't required for the foreach loop. It's just nice to have.

Pass an array to a function (And use the function to split the array)

I want to pass a string array (separated by commas), then use a function to split the passed array by a comma, and add in a delimiter in place of the comma.
I will show you what I mean in further detail with some broken code:
String FirstData = "1";
String SecondData = "2" ;
String ThirdData = "3" ;
String FourthData = null;
FourthData = AddDelimiter(FirstData,SecondData,ThirdData);
public String AddDelimiter(String[] sData)
{
// foreach ","
String OriginalData = null;
// So, here ... I want to somehow split 'sData' by a ",".
// I know I can use the split function - which I'm having
// some trouble with - but I also believe there is some way
// to use the 'foreach' function? I wish i could put together
// some more code here but I'm a VB6 guy, and the syntax here
// is killing me. Errors everywhere.
return OriginalData;
}
Syntax doesn't matter much here, you need to get to know the Base Class Library. Also, you want to join strings apparently, not split it:
var s = string.Join(",", arrayOFStrings);
Also, if you want to pass n string to a method like that, you need the params keyword:
public string Join( params string[] data) {
return string.Join(",", data);
}
To split:
string[] splitString = sData.Split(new char[] {','});
To join in new delimiter, pass in the array of strings to String.Join:
string colonString = String.Join(":", splitString);
I think you are better off using Replace, since all you want to do is replace one delimiter with another:
string differentDelimiter = sData.Replace(",", ":");
If you have several objects and you want to put them in an array, you can write:
string[] allData = new string[] { FirstData, SecondData, ThirdData };
you can then simply give that to the function:
FourthData = AddDelimiter(allData);
C# has a nice trick, if you add a params keyword to the function definition, you can treat it as if it's a function with any number of parameters:
public String AddDelimiter(params String[] sData) { … }
…
FourthData = AddDelimiter(FirstData, SecondData, ThirdData);
As for the actual implementation, the easiest way is to use string.Join():
public String AddDelimiter(String[] sData)
{
// you can use any other string instead of ":"
return string.Join(":", sData);
}
But if you wanted to build the result yourself (for example if you wanted to learn how to do it), you could do it using string concatenation (oneString + anotherString), or even better, using StringBuilder:
public String AddDelimiter(String[] sData)
{
StringBuilder result = new StringBuilder();
bool first = true;
foreach (string s in sData)
{
if (!first)
result.Append(':');
result.Append(s);
first = false;
}
return result.ToString();
}
One version of the Split function takes an array of characters. Here is an example:
string splitstuff = string.Split(sData[0],new char [] {','});
If you don't need to perform any processing on the parts in between and just need to replace the delimiter, you could easily do so with the Replace method on the String class:
string newlyDelimited = oldString.Replace(',', ':');
For large strings, this will give you better performance, as you won't have to do a full pass through the string to break it apart and then do a pass through the parts to join them back together.
However, if you need to work with the individual parts (to recompose them into another form that does not resemble a simple replacement of the delimiter), then you would use the Split method on the String class to get an array of the delimited items and then plug those into the format you wish.
Of course, this means you have to have some sort of explicit knowledge about what each part of the delimited string means.

Parsing formatted string

I am trying to create a generic formatter/parser combination.
Example scenario:
I have a string for string.Format(), e.g. var format = "{0}-{1}"
I have an array of object (string) for the input, e.g. var arr = new[] { "asdf", "qwer" }
I am formatting the array using the format string, e.g. var res = string.Format(format, arr)
What I am trying to do is to revert back the formatted string back into the array of object (string). Something like (pseudo code):
var arr2 = string.Unformat(format, res)
// when: res = "asdf-qwer"
// arr2 should be equal to arr
Anyone have experience doing something like this? I'm thinking about using regular expressions (modify the original format string, and then pass it to Regex.Matches to get the array) and run it for each placeholder in the format string. Is this feasible or is there any other more efficient solution?
While the comments about lost information are valid, sometimes you just want to get the string values of of a string with known formatting.
One method is this blog post written by a friend of mine. He implemented an extension method called string[] ParseExact(), akin to DateTime.ParseExact(). Data is returned as an array of strings, but if you can live with that, it is terribly handy.
public static class StringExtensions
{
public static string[] ParseExact(
this string data,
string format)
{
return ParseExact(data, format, false);
}
public static string[] ParseExact(
this string data,
string format,
bool ignoreCase)
{
string[] values;
if (TryParseExact(data, format, out values, ignoreCase))
return values;
else
throw new ArgumentException("Format not compatible with value.");
}
public static bool TryExtract(
this string data,
string format,
out string[] values)
{
return TryParseExact(data, format, out values, false);
}
public static bool TryParseExact(
this string data,
string format,
out string[] values,
bool ignoreCase)
{
int tokenCount = 0;
format = Regex.Escape(format).Replace("\\{", "{");
for (tokenCount = 0; ; tokenCount++)
{
string token = string.Format("{{{0}}}", tokenCount);
if (!format.Contains(token)) break;
format = format.Replace(token,
string.Format("(?'group{0}'.*)", tokenCount));
}
RegexOptions options =
ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None;
Match match = new Regex(format, options).Match(data);
if (tokenCount != (match.Groups.Count - 1))
{
values = new string[] { };
return false;
}
else
{
values = new string[tokenCount];
for (int index = 0; index < tokenCount; index++)
values[index] =
match.Groups[string.Format("group{0}", index)].Value;
return true;
}
}
}
You can't unformat because information is lost. String.Format is a "destructive" algorithm, which means you can't (always) go back.
Create a new class inheriting from string, where you add a member that keeps track of the "{0}-{1}" and the { "asdf", "qwer" }, override ToString(), and modify a little your code.
If it becomes too tricky, just create the same class, but not inheriting from string and modify a little more your code.
IMO, that's the best way to do this.
It's simply not possible in the generic case. Some information will be "lost" (string boundaries) in the Format method. Assume:
String.Format("{0}-{1}", "hello-world", "stack-overflow");
How would you "Unformat" it?
Assuming "-" is not in the original strings, can you not just use Split?
var arr2 = formattedString.Split('-');
Note that this only applies to the presented example with an assumption. Any reverse algorithm is dependent on the kind of formatting employed; an inverse operation may not even be possible, as noted by the other answers.
A simple solution might be to
replace all format tokens with (.*)
escape all other special charaters in format
make the regex match non-greedy
This would resolve the ambiguities to the shortest possible match.
(I'm not good at RegEx, so please correct me, folks :))
After formatting, you can put the resulting string and the array of objects into a dictionary with the string as key:
Dictionary<string,string []> unFormatLookup = new Dictionary<string,string []>
...
var arr = new string [] {"asdf", "qwer" };
var res = string.Format(format, arr);
unFormatLookup.Add(res,arr);
and in Unformat method, you can simply pass a string and look up that string and return the array used:
string [] Unformat(string res)
{
string [] arr;
unFormatLoopup.TryGetValue(res,out arr); //you can also check the return value of TryGetValue and throw an exception if the input string is not in.
return arr;
}

Categories