Showing the intersection between two strings - c#

I am trying to find the intersection between two strings. For example, if string one was my car is bad, and string two was my horse is good, it would return my is.
This is my code:
public static string intersection2(string x1, string x2)
{
string[] string1 = x1.Split(' ');
string[] string2 = x2.Split(' ');
string[] m = string1.Distinct();
string[] n = string2.Distinct();
string Test;
var results = m.Intersect(n,StringComparer.OrdinalIgnoreCase);
Test = results.ToString();
return Test;
}
But I get the error System.Linq.Enumerable+d__921[System.String]`. Could someone explain what's going on, and how I can fix it?

You're not seeing an error - what you are seeing is the fully qualified name of the type of result, which is System.Linq.Enumerable+d_921[System.String]. This is the default behavior for ToString(), unless it is overridden in an inheriting class. See Object.ToString().
To show the results of the intersection, you can use String.Join, like this:
Test = String.Join(" ", results);
Which would produce my is.
Note that your code as posted wouldn't compile:
string[] m = string1.Distinct();
string[] n = string2.Distinct();
The above lines generated a Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<string>' to 'string[]'. Adding .ToArray() is one way to resolve this. Full code below:
public static string intersection2(string x1, string x2)
{
string[] string1 = x1.Split(' ');
string[] string2 = x2.Split(' ');
string[] m = string1.Distinct().ToArray();
string[] n = string2.Distinct().ToArray();
string Test;
var results = m.Intersect(n, StringComparer.OrdinalIgnoreCase);
Test = String.Join(" ", results);
return Test;
}

Your logic is okay, you can make it work by fixing a little bit
public static string intersection2(string x1, string x2)
{
string[] string1 = x1.Split(' ');
string[] string2 = x2.Split(' ');
var m = string1.Distinct();
var n = string2.Distinct();
var results = m.Intersect(n, StringComparer.OrdinalIgnoreCase);
//The result is a list of string, so we just have to concat them
var test = " ";
foreach(var k in results) test += k + " ";
return test;
}
Working fiddle: https://dotnetfiddle.net/joO0d9

That's basically happened because you tired to get the string representation of an IEnumerable<string> and it's completely normal because it returns the default ToString() of object class. So in order to fix that you should somehow make your own string representation, which will be s.t. like this:
string[] string1 = x1.Split(' ');
string[] string2 = x2.Split(' ');
string Test;
var results = string1.Intersect(string2, StringComparer.OrdinalIgnoreCase);
Test = string.Join(" ", results);
also note that there is no need to get Distinct result of your arrays, because Intersect is a set operation and naturally returns the Distict result!

This program gets intersection of 2 strings (assuming duplication is allowed)
public String getIntersection(String s1, String s2) {
String common = "";
for (int i = 0; i < s1.length(); i++) {
for (int j = 0; j < s2.length(); j++) {
if (s1.length() == 0 || s1.length() == 0)
return common;
if (s1.charAt(i) == s2.charAt(j)) {
common = common + s1.charAt(i);
// delete character from each if there is a match
s1 = s1.substring(0, i) + s1.substring(i + 1);
s2 = s2.substring(0, j) + s2.substring(j + 1);
i = -1;
break;
}
}
}
return common;
}

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);
}

Is there a simple way to apply grammatical casing to a string?

I am developing a Xamarin.Forms application on UWP
I have an Editor control - Basically a multi-line TextBox
I am trying to apply some simple grammatical casing to the string basically the following:
Capitalise the word "I"
Capitalise the First word
Capitalise the First word after a full stop.
I have managed to do the first two, and am a bit stuck on the third and was wondering if there is an easier way or whether my algorithm can be adapted.
What I have so far is:
public static string ToGramaticalCase(this string s)
{
var thingsToCapitalise = new String[] {"i"};
string newString = string.Empty;
if (!string.IsNullOrEmpty(s))
{
var wordSplit = s.Split(' ');
if (wordSplit.Count() > 1)
{
var wordToCapitalise = wordSplit.First();
wordToCapitalise = wordToCapitalise.Substring(0, 1).ToUpper() + wordToCapitalise.Substring(1);
var value = wordToCapitalise + s.Substring(wordToCapitalise.Length);
foreach (var item in thingsToCapitalise)
{
value = value.Replace(string.Format(" {0} ", item), string.Format(" {0} ", item.ToUpper()));
}
newString = value;
}
}
return newString;
}
This method will capitalize all words after ". ":
[Test]
public void Test()
{
var result = NewSentenceWithUpperLetter("Sentence one. sentence two.");
// result will be 'Sentence one. Sentence two.'
}
private string NewSentenceWithUpperLetter(string text)
{
var splitted = text.Split(' ');
for (var i = 1; i < splitted.Length; i++)
{
if (splitted[i - 1].EndsWith("."))
{
splitted[i] = splitted[i][0].ToString().ToUpper() + splitted[i].Substring(1);
}
}
return string.Join(" ", splitted);
}
Just split the string also on full stop. Change this line:
var wordSplit = s.Split(' ');
Into this:
var wordSplit = s.Split(new char[] { ' ', '.' },StringSplitOptions.RemoveEmptyEntries);
Edit
This extension method would do what you want:
public static string ToTitleCase(this string input)
{
string output =
String.Join(" ", input.Split(new char[] { ' ' },StringSplitOptions.RemoveEmptyEntries)
.ToList()
.Select(x => x = x.Length>1?
x.First().ToString().ToUpper() + x.Substring(1):
x.First().ToString().ToUpper()));
output =
String.Join(".", output.Split(new char[] { '.' },StringSplitOptions.RemoveEmptyEntries)
.ToList()
.Select(x => x = x.Length > 1 ?
x.First().ToString().ToUpper() + x.Substring(1) :
x.First().ToString().ToUpper()));
return output;
}
Test string: string input = "i try this test sentence .now it works as i want";
Output: I Try This Test Sentence .Now It Works As I Want

List and array comparison

I have a requirement wherein I have a value in Viewbag.Keyword like "Johnson and Jen" so I have to split this value and compare it with List.
I was trying the below code but facing error some or the other way(eg; this is char not string and so on) and it doesn't look like smart coding as per latest functionalities available in framework 4.5
var str = Convert.ToString(ViewBag.Keyword);
string[] str1 = str.Split(' ');
for (int j = 0; j < str1.Length;j++)
{
string str2 = Convert.ToString(str[j]);
if (result.Document.ContactName.IndexOf(str2,
StringComparison.CurrentCultureIgnoreCase) != -1)
Note: "ContactName" is string.
Please help with some latest code which improves performance.
You can use linq to check if result.Document.Name contains a word from array.
var str = Convert.ToString(ViewBag.Keyword);
string[] str1 = str.Split(' ');
var names = str1.Where(x => (result.Document.ContactName.Contains(x))).ToList();
You can compare those names are on that string like below,
Remember comparison is case sensitive
var str = Convert.ToString(ViewBag.Keyword);
string[] str1 = str.Split(' ');
if(str1.Any(result.Document.ContactName.Contains)){
//Do Something
}
Example -
var str = "Johnson and Jen";
string[] str1 = str.Split(' ');
string result = "Jendasdbnoahsdasnd"; // I assume your ContactName result is like this
if (str1.Any(result.Contains)) // This gives true because Jen in the string
{
//Do Something
}
But, for the string result = "jendasdbnoahsdasnd" it gives false because of the case.
If you need to check for the exact match of the words you get by splitting the keyword string using a white space against the contact name property from the collection then you can use a regular expression to do that.
The regular expression is of the form \bTheWordGoesHere\b where \b is the word boundary delimiter
Check this sample code snippet.
var keyword = "Johnson and Jen";
var arr = keyword.Split(' ');
var contactName = "Johnson anderson mobile";
for (var i = 0; i < arr.Length; i++)
{
var pattern = string.Format("\\b{0}\\b", arr[i]);
if (Regex.IsMatch(contactName, pattern, RegexOptions.IgnoreCase))
{
// do something
Console.WriteLine("contactName contains the word \"" + arr[i] + "\"");
}
}
rextester link
Below is a sample code for doing the same using clean code
var str = Convert.ToString(ViewBag.Keyword);
var possibleNames = str.split(' ');
//to check if any match exists
bool anyMatch = possibleNames.Any(n => n.Equals(result.Document.ContactName, StringComparison.InvariantCultureIgnoreCase));
//get matched names
var matchedNames = possibleNames.Where(n => n.Equals(result.Document.ContactName, StringComparison.InvariantCultureIgnoreCase));
//do whatever you want with matchedNames now
var array = matchedNames.ToArray();
var list = matchedNames.ToList();
You can split the string "Johnson and Jen" by using another string i.e. " and " this will exactly give you the names which will be appropriate to check against the contact name.
You can check about the Split function here and here
To check whether a property contains a specified string or not you can use the IndexOf method - a simple sample code snippet is given below, you can run this sample code snippet here.
var keyword = "Johnson and Jen";
var arr = keyword.Split(new string[] { " and " }, StringSplitOptions.None);
var contactName = "Johnson";
for (var i = 0; i < arr.Length; i++)
{
if (contactName.IndexOf(arr[i], StringComparison.OrdinalIgnoreCase) >= 0)
{
// do something
Console.WriteLine("contactName contains the string \"" + arr[i] + "\"");
}
}
The code snippet for your scenario would be as follows and in your code you don't need the unnecessary type casting i.e. string str2 = Convert.ToString(str[j]); because str[j] is already a string
var keyword = Convert.ToString(ViewBag.Keyword);
var arr = name.Split(new string[] { " and " }, StringSplitOptions.None);
for (int i = 0; i < arr.Length; i++)
{
if (result.Document.ContactName.IndexOf(arr[i], StringComparison.OrdinalIgnoreCase) != -1)
{
// do something
}
}
Using the StringComparison parameter with its value as StringComparison.OrdinalIgnoreCase will do a case insensitive search

Parsing a string with, seemingly, no delimiter

I have the following string that I need to parse out so I can insert them into a DB. The delimiter is "`":
`020 Some Description `060 A Different Description `100 And Yet Another `
I split the string into an array using this
var responseArray = response.Split('`');
So then each item in the responseArrray[] looks like this: 020 Some Description
How would I get the two different parts out of that array? The 1st part will be either 3 or 4 characters long. 2nd part will be no more then 35 characters long.
Due to some ridiculous strangeness beyond my control there is random amounts of space between the 1st and 2nd part.
Or put the other two answers together, and get something that's more complete:
string[] response = input.Split(`);
foreach (String str in response) {
int splitIndex = str.IndexOf(' ');
string num = str.Substring(0, splitIndex);
string desc = str.Substring(splitIndex);
desc.Trim();
}
so, basically you use the first space as a delimiter to create 2 strings. Then you trim the second one, since trim only applies to leading and trailing spaces, not everything in between.
Edit: this a straight implementation of Brad M's comment.
You can try this solution:
var inputString = "`020 Some Description `060 A Different Description `100 And Yet Another `";
int firstWordLength = 3;
int secondWordMaxLength = 35;
var result =inputString.Split('`')
.SelectMany(x => new[]
{
new String(x.Take(firstWordLength).ToArray()).Trim(),
new String(x.Skip(firstWordLength).Take(secondWordMaxLength).ToArray()).Trim()
});
Here is the result in LINQPad:
Update: My first solution has some problems because the use of Trim after Take.Here is another approach with an extension method:
public static class Extensions
{
public static IEnumerable<string> GetWords(this string source,int firstWordLengt,int secondWordLenght)
{
List<string> words = new List<string>();
foreach (var word in source.Split(new[] {'`'}, StringSplitOptions.RemoveEmptyEntries))
{
var parts = word.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
words.Add(new string(parts[0].Take(firstWordLengt).ToArray()));
words.Add(new string(string.Join(" ",parts.Skip(1)).Take(secondWordLenght).ToArray()));
}
return words;
}
}
And here is the test result:
Try this
string response = "020 Some Description060 A Different Description 100 And Yet Another";
var responseArray = response.Split('`');
string[] splitArray = {};
string result = "";
foreach (string it in responseArray)
{
splitArray = it.Split(' ');
foreach (string ot in splitArray)
{
if (!string.IsNullOrWhiteSpace(ot))
result += "-" + ot.Trim();
}
}
splitArray = result.Substring(1).Split('-');
string[] entries = input.Split('`');
foreach (string s in entries)
GetStringParts(s);
IEnumerable<String> GetStringParts(String input)
{
foreach (string s in input.Split(' ')
yield return s.Trim();
}
Trim only removes leading/trailing whitespace per MSDN, so spaces in the description won't hurt you.
If the first part is an integer
And you need to account for some empty
For me the first pass was empty
public void parse()
{
string s = #"`020 Some Description `060 A Different Description `100 And Yet Another `";
Int32 first;
String second;
if (s.Contains('`'))
{
foreach (string firstSecond in s.Split('`'))
{
System.Diagnostics.Debug.WriteLine(firstSecond);
if (!string.IsNullOrEmpty(firstSecond))
{
firstSecond.TrimStart();
Int32 firstSpace = firstSecond.IndexOf(' ');
if (firstSpace > 0)
{
System.Diagnostics.Debug.WriteLine("'" + firstSecond.Substring(0, firstSpace) + "'");
if (Int32.TryParse(firstSecond.Substring(0, firstSpace), out first))
{
System.Diagnostics.Debug.WriteLine("'" + firstSecond.Substring(firstSpace-1) + "'");
second = firstSecond.Substring(firstSpace).Trim();
}
}
}
}
}
}
You can get the first part by finding the first space and make a substring. The second is also a Substring. Try something like this.
foreach(string st in response)
{
int index = response.IndexOf(' ');
string firstPart = response.Substring(0, index);
//string secondPart = response.Substring(response.Lenght-35);
//better use this
string secondPart = response.Substring(index);
secondPart.Trim();
}

c# Sum to string of Char array

So I have these two functions,
public static string[] CharToHex(string str, string prefix, string delimeter)
{
List<string> list = new List<string>();
foreach (char c in str)
{
list.Add(prefix + String.Format("{0:X2}",(int)c) + delimeter);
}
return list.ToArray();
}
public static string[] StrToChar(string str, string prefix, string delimeter)
{
List<string> list = new List<string>();
foreach (char c in str)
{
list.Add(prefix + (int)c + delimeter);
}
return list.ToArray();
}
Basically, I'm trying to show the Sum'd value of both returned arrays in a label.
I created a function to calculate a sum,
public static string ArraySum(int[] array)
{
string sum = array.Sum().ToString();
return sum;
}
And another function to take the string array and convert it to a string,
public static string StringArrayToString(string[] array)
{
StringBuilder builder = new StringBuilder();
foreach (string value in array)
{
builder.Append(value);
}
return builder.ToString();
}
This is how I'm putting it all together,
string[] dec = StrToChar(txtInput.Text, txtPrefix.Text, txtDelimiter.Text);
string[] hex = CharToHex(txtInput.Text, txtPrefix.Text, txtDelimiter.Text);
string decStr = StringArrayToString(dec);
string hexStr = StringArrayToString(hex);
int[] decCount = dec.Select(x => int.Parse(x)).ToArray();
int[] hexCount = hex.Select(x => int.Parse(x)).ToArray();
var builder = new StringBuilder();
Array.ForEach(decCount, x => builder.Append(x));
var res = builder.ToString();
txtDecimal.Text = decStr;
txtHex.Text = hexStr;
lblDecimalSum.Text = res;
The issue here is, this obviously isn't working, it also seems horribly inefficient, there has to be an easier way of doing all of this and also, my sum isn't properly summing up the array elements.
I'm not entirely sure how to go about doing this and any assistance / feedback would be greatly appreciated.
Thank you kindly.
If I understand you correctly, you're trying to get the add the value of each character of a string together, not parse an int from a string and add those together. If that's the case, you can do it with linq:
string x = "xasdgdfhdsfh";
int sum = x.Sum(b => b);
In fact using linq, you can accomplish everything you want to do:
string x = "xasdgdfhdsfh";
string delim = txtDelimiter.Text;
string prefix = txtPrefix.Text;
lblDecimalSum.Text = x.Sum(c => c).ToString();
txtDecimal.Text =
string.Join(delim, x.Select(c => prefix + ((int)c).ToString()));
txtHex.Text =
string.Join(delim, x.Select(c => prefix + ((int)c).ToString("X2")));

Categories

Resources