CollectionAssert failed to do exact match - need best approach - c#

I'm trying to compare two lists using CollectionAssert but it failed in comparing exact match and also it is not telling which value is incorrect
List<string> ExpectedList = new List<string>() { "apple","orange","grapes","mango"};
List<string> ActualList = new List<string>() { "gova","orange","GRAP"};
CollectionAssert.AreEqual(ExpectedList, ActualList)
Expected results should be in String:
"apple gova, grape GRAP, empty Mango"
How can I do it more efficiently or simply?
Is there any other Assertion available in C#?

Use Zip method like this:
List<string> ExpectedList = new List<string>() {"apple", "orange", "grapes", "mango"};
List<string> ActualList = new List<string>() {"gova", "orange", "GRAP"};
var result = ExpectedList.Zip(ActualList, (first,second) => first != second ?
$"Mismatch = {first} , {second}" : "")
.Concat(ExpectedList.Skip(ActualList.Count))
.Concat(ActualList.Skip(ExpectedList.Count))
.Where(c=>!string.IsNullOrWhiteSpace(c)).ToList();
And if you want to get the result as string:
string theStringVersion = string.Join(",", result);

Related

Can I sort a List<string> by integers inside of them?

For example;
List<string> list = new List<string>{
"1[EMPTY]", "2[EMPTY]", "3[EMPTY]", "4[EMPTY]", "5[EMPTY]", "6[EMPTY]", "7[EMPTY]", "8[EMPTY]", "9[EMPTY]", "10[EMPTY]", "11[EMPTY]", "12[EMPTY]"
};
When I use
list.Sort();
Output:
1[EMPTY] 10[EMPTY] 11[EMPTY] 12[EMPTY] 2[EMPTY] 3[EMPTY] 4[EMPTY] 5[EMPTY] 6[EMPTY] 7[EMPTY] 8[EMPTY] 9[EMPTY]
I want 1-2-3-4-5-6-7-8-9-10-11-12.
How can i solve this problem?
(Sorry my English is bad :{)
You can use OrderBy. Basically trick is to sort the string so parsing as int. and getting the value till the first occurance of [.
List<string> list = new List<string>{
"1[EMPTY]", "2[EMPTY]", "3[EMPTY]", "4[EMPTY]", "5[EMPTY]", "6[EMPTY]", "7[EMPTY]", "8[EMPTY]", "9[EMPTY]", "10[EMPTY]", "11[EMPTY]", "12[EMPTY]"
};
list = list.OrderBy(c => int.Parse(c.Substring(0, c.IndexOf('[')))).ToList();

How can I only store the second part of a string in a list?

I have a list Textlist1 that contains only strings. Each item in the list begins with the same text: "sentence.text.", but I only want to store the second part of the string in another list, I don't want to store the first part "sentence.text." in the list Textlist2.
For example:
List<string> Textlist1 = new List<string>();
List<string> Textlist2 = new List<string>();
The full strings are stored in Textlist1.
Textlist1[0] = "sentence.text.My name is Fred"
Textlist1[1] = "sentence.text.Jenny is my sister"
How can I only add "My name is Fred" and "Jenny is my sister" to Textlist2?
The result should be like this:
Textlist2[0] = "My name is Fred"
Textlist2[1] = "Jenny is my sister"
See online result: https://dotnetfiddle.net/MpswLZ
List<string> Textlist1 = new List<string>() {
"sentence.text.My name is Fred",
"sentence.text.Jenny is my sister"
};
List<string> Textlist2 = new List<string>();
Textlist2 = Textlist1.Select(item => item.Split('.')[2]).ToList();
You can use Linq. (You need do add using System.Linq)
Textlist2= Textlist1
.Select(i=> i.Substring("sentence.text.".Length))
.ToList();
Split the input strings by the periods, limiting the split to 3. Then take the last entry from the array that split produces.
Textlist2[0] = Textlist1[0].Split('.', 3)[2];
Textlist2[1] = Textlist1[1].Split('.', 3)[2];
You could use Regex.Replace the text.
var regex = new Regex("^sentence.text.",RegexOptions.Compiled);
Textlist2.AddRange(Textlist1.Select(x=>regex.Replace(x,string.Empty)));
The "^" in Regex ensure the required text ("sentence.text") is matched only at the beginning of string and not else where.
Sample Input
Sample Output
List<string> Textlist1 = new List<string>
{
"sentence.text.a",
"sentence.text.b"
};
string prefix = "sentence.text.";
List<string> Textlist2 = Textlist1.Select(x => x.Substring(prefix.Length)).ToList();
https://dotnetfiddle.net/oFhvfs
There are ultimately many ways of doing this, this is just one solution. Which approach you choose depends on how complex the pattern replacement is. I've gone with a simplistic approach as your example is a very simple case.

How define a string array list?

I'd like to define a list whose element is a 3-elements array. Below codes seems ok:
List<dynamic[]> bb = null;
but when I try:
List<dynamic[3]> bb = null;
It throws error. Sure I can create a class/struct for that. But is there a way to define it directly?
Here is one way:
var list = new List<string[]>();
list.Add(new string[3] { "1", "2", "3" });
list.Add(new string[2] { "1", "2" });
Update:
#Ilya's answer shows a solution with dynamic, but I advise you against using dynamic. If you know the structure of the objects create a class or use a tuple, e.g.
var list = new List<(int id, string name, uint reputation)>();
list.Add((298540, "xiaoyafeng", 11));
list.Add((2707359, "Ilya", 3576));
list.Add((581076, "tymtam", 4421));
list.Add((3043, "Joel Coehoorn", 294378));
I'm not sure what your issue was; your title talks about a "string array list", but your posted code describes a list of arrays of dynamic.
I'm not sure I'll ever have reason to create a list of arrays of dynamic, but to show that the code that you discussed in your post can work, this works for me:
var stuff = new List<dynamic[]>
{
new dynamic[] {1, "string"},
new dynamic[] {DateTime.Now, 45.0}
};
But, as noted in other answers, dynamic is a great answer to several classes of questions. But, it's not the right answer here. The right answer to the title of your question (not the description) will use a list of string arrays (as has been pointed in the other answers:
var otherStuff = new List<string[]>
{
new string[] {"Now", "Is", "the", "time"},
new string[] {"for all", "good men, etc."}
};
It seems that you need something like this:
List<dynamic[]> bb = new List<dynamic[]>();
bb.Add(new dynamic[3]); // here you add a 3-element array
bb.Add(new dynamic[3] { "a", "b", "c" }); // here you add another one 3-element array
// List containing a string array with 3 nulls in it
var aa = new List<string[]> {new string[3]};
// List containing a string array with 3 strings in it
var bb = new List<string[]> {new[] {"a", "b", "c"}};

C# get count value of type object

I am trying to get the count value of my list witch is in type object.
This is fictive code for demonstrating what i am working with
object test = new List<string>() { "test1", "test2" };
This is what i am trying to achive
test.count
You can't fetch a property that isn't known to the type of your variable. You should cast it to the right type:
List<string> test = new List<string>() { "test1", "test2" };
int count = test.Count;
If you feel like it, you can use var, which will translate to the exact same as above:
var /*actually List<string>*/ test = new List<string>() { "test1", "test2" };
Unless it's a must for your test to be of object type (which I don't see why it need to be in the question).
Changing
object test = new List<string>() {"test1","test2"};
to
List<string> test = new List <string>() {"test1","test2"};
will allow you to use the count method
If you know that your list is string type then you should use string type list instead of object. like below
List<string> lst = new List<string>() { "test1", "test2" };
if (lst.Count() > 0)
{
//Do some thing here
}
You can use following code to get count of object. You can achieve this using Reflection.
object test = new List<string>() { "test1", "test2" };
var property = typeof(ICollection).GetProperty("Count");
int count = (int)property.GetValue(test, null);
NOTE:
Reflection provides facility to metaprogramming. The benefit of using Reflection in SPECIAL cases is it gives developers a power to access Assembly Runtime regardless of any types. I suggest to use Reflection in special scenarios only.
Proper way is to cast object to type
List<string> test = new List<string>() { "test1", "test2" };
int count = test.Count;
Cast object to a particular type while using.
object test = new List<string>() { "test1", "test2" };
int count = ((List<string>) test).Count;
OR
You can simply use var to initialize the list for avoiding casting everytime of usage.
var test = new List<string>() { "test1", "test2" };
int count = test.Count;
OR
You can initialize with a particular type.
List<string> test = new List<string>() { "test1", "test2" };
int count = test.Count;
It will always be the type object when i get it back from my method. I found a solution
List<string> tt = (List<string>)test;
myCountValue = tt.Count

Compare the first letters of a list

I've a list with some strings like this:
List<String> data = new List<String>
{
"marine",
"blue",
"SEM",
"seven",
"sensible",
"six"
};
Now I want to compare this list with a string and add the matching items to a new list:
String input = "se";
List<String> newList = new List<String>;
The matching condition is, that the first letters should be the same (case-sensitive). In this case the newList contains:
"seven" and "sensible"
How is the most performant solution?
var newList = data.Where(s => s.StartsWith(input)).ToList();

Categories

Resources