I have a string[] which contains value {"data1","data2","data3"}.
and i have a GenericList which contains
data2
data4
two records
i want to get the common datas which is avail in string[] and the genericList
Have you tried something like
string[] s = {"data1", "data2", "data3"};
List<string> list = new List<string> { "data2", "data3" };
var commonList = list.Intersect(s);
Have a look at Enumerable.Intersect Method (IEnumerable, IEnumerable)
Assuming it's a List<string> and you're using .NET 3.5 or higher, you can use the Intersect method from LINQ to Objects:
var intersection = stringArray.Intersect(stringList);
Note that this will return a lazily-evaluated IEnumerable<string>. If you need it in an array or a list, call the relevant method:
var intersectionArray = stringArray.Intersect(stringList).ToArray();
// or
var intersectionList = stringArray.Intersect(stringList).ToList();
Also note that this is a set operation - so the result will not contain any duplicates, even if there is duplication of a particular element in both the original collections.
Take a look at the Intersect extension method here
string[] c1 = { "data1", "data2", "data3" };
string[] c2 = { "data2", "data4" };
IEnumerable<string> both = c1.Intersect(c2);
foreach (string s in both) Console.WriteLine(s);
Will print data2.
Related
I'm fairly new to C#, and i've come across a problem trying to split on list elements.
I have a resource file containing string properties as such:
ResourceFile
ResourceFile
I've collected them in a List as:
public List<String> RawNewsList1 = new List<String>()
{
{Resource.NewsContentAndroid1},
{Resource.NewsMetaAndroid1},
};
I'm trying to split on the semicolons but only get results from my second list item.
My split look like this:
public void FilterRawNews()
{
String[] seperator = { ";;;" };
String[] filteredList1 = { "" };
for (int i = 0; i < RawNewsList1.Count; i++) {
filteredList1 = RawNewsList1[i].Split(seperator, 5,
StringSplitOptions.RemoveEmptyEntries);
}
foreach (String s in filteredList1)
{
Console.WriteLine(s);
}
}
Its only prints:
110
2.8
02-07-2020
What am i doing wrong?
Thanks in advance!
The filteredList1 variable is first filled with data from your the first resource, then at the next loop the variable's content is replaced with the data coming from the second resource.
You can use a List<string> instead that has the AddRange method to continuosly add elements to the list
List<string> filteredList1 = new List<string>();
for (int i = 0; i < RawNewsList1.Count; i++) {
filteredList1.AddRange(RawNewsList1[i].Split(seperator, 5,StringSplitOptions.RemoveEmptyEntries));
}
From this we could simplify the code to one-liner with
filteredList = RawNewsList1.SelectMany(a => a.Split(seperator,5, StringSplitOptions.RemoveEmptyEntries)).ToList();
So, what's happen in that single line? That syntax is used when you work with objects that can be treated as a sequence of data. In this context your array RawNewsList1 is a sequence of data and we can use the IEnumerable extensions brought to us by using the Linq namespace. The SelectMany extension requires a lambda expression ( a => ....) that is used to produce the instructions where each element of the sequence (a) is passed to an expression that returns another sequence of data (the array returned by Split). The sequence returned is accumulated to the sequence produced by the next elements from the original RasNewsList1. Finally the accumulated sequence is materialized with the call to ToList()
You are overwriting filteredList1 in each iteration.
That is why you only get the last result.
Just declare filteredList1 as a list and and use AddRange().
Edit: or use LINQ:
var raw = new List<string>() { "111;;;222", "333;;;444" };
String[] seperator = { ";;;" };
var filterlist1 = raw.SelectMany(r => r.Split(seperator, 5, StringSplitOptions.RemoveEmptyEntries)).ToList();
.net fiddle: https://dotnetfiddle.net/27wJLc
I have two lists of strings, the 'all' list and a list to compare, I then want to return the strings from the 'All' list that did not match:
public static void Main()
{
List<string> ratiodGids = new List<string>();
List<string> allGids = new List<string>();
List<string> notRatiodGids = new List<string>();
allGids.Add("tom");
allGids.Add("bob");
allGids.Add("bill");
allGids.Add("tim");
allGids.Add("sam");
ratiodGids.Add("tom");
ratiodGids.Add("tim");
ratiodGids.Add("sam");
foreach(var g in ratiodGids)
{
if(!allGids.Contains(g))
{
notRatiodGids.Add(g);
}
}
Console.WriteLine(notRatiodGids.Count);
foreach(var i in notRatiodGids)
Console.WriteLine(i);
}
I'm pretty sure I can re-type everything back to IEnumerable then use Intersect or Except, but that will take some work. So I wanted to see if it was possible with Lists before doing that.
With the code I have, the list returns nothing. If I remove the '!' I get back tom, tim, sam. So it works one way, but not the other.
UPDATE: The result I want is just the strings from ratiodGids that don't exist in allGids. Order does not matter. Also, I have tried using Exists(), Except(), Any(), Where() and they both give me the "List does not contain a method called blah ...".
Well, you can use Except() on a List as well, because it implements IList which derives from IEnumerable.
Update
As pointed out in the comments, the Linq-methods are extension methods on IEnumerable. To use them, you have to add their namespace by adding: using System.Linq;
You can compare two lists and return a new list with only the differences like so:
List<string> difference = list1.Except(list2).ToList();
You can do it like:
var results = allGids.Where( a=> !ratiodGids.Contains(a))
if you want to get uniqe items from both lists then:
var results = allGids.Where( a=> !ratiodGids.Contains(a))
.Union(ratiodGids.Where( a=> !allGids.Contains(a)));
change this
foreach(var g in ratiodGids)
{
if(!allGids.Contains(g))
{
notRatiodGids.Add(g);
}
}
to this
foreach(var g in allGids)
{
if(!ratioGids.Contains(g))
{
notRatiodGids.Add(g);
}
}
To be clear, if listA = { A,B,C } and listB = { B,C,D } do you want your result to be { A,D }? If so, here's one way:
var union = listA.Union(listB);
var intersection = listA.Intersect(listB);
var outside = union.Except(intersection);
I have got a simple question I am having a list:
List<string> test = new List<string> {"one", "two", "three", "four"}
Now I want to take for example value "three" and get all elements after it, so it would be looking like:
List<string> test = new List<string> {"three", "four"}
But we do not know where list end so it can be list of many elements and we can not define end as const.
Is it possible?
It sounds like you're looking for SkipWhile from LINQ:
test = test.SkipWhile(x => x != "three").ToList();
That will skip everything until (but not including) the "three" value, then include everything else. It then converts it to a list again.
Since you assign the filtered list back to initial one, then just remove first items up to "three" one:
int count = test.IndexOf("three");
test.RemoveRange(0, count < 0 ? test.Count : count);
This implementation doesn't create additional list, but modifies existing one.
This might do the trick for you
var list2 = test.Skip(2).Take(test.Count).ToList();
or better
var list3 = test.Skip(2).ToList();
Without LINQ it could be done something like this
List<string> outtest = new List<string>();
bool drty = false;
foreach(string st in test)
{
if(st == "three") //or whatever is the input.
drty = true;
if(drty)
outtest.Add(st);
}
I have a list o that has strings:
"Hist 2368#19:00:00#20:30:00#Large Conference Room",
"Hist 2368#09:00:00#10:30:00#Large Conference Room",
I want to add those strings to this:
var lines = new[]
{
"Meeting#19:00:00#20:30:00#Conference",
};
How would I use the data from the list o and insert it into lines?
Array are be nature, fixed-length. You need to create a new array, and assign it to lines.
lines = lines.Concat(o).ToArray();
Alternately,
lines = o.AddRange(lines).ToArray();
UPDATE: Fixed dumb mistake.
Since Lines is already an array, you'll need to merge the values into your list first:
foreach (var item in lines)
o.Add(item);
Then change o to an Array:
o.ToArray(); ///returns String[] with all three values.
You can also use .concat() as others have pointed out, which will internally do the same.
An additional thing to consider is the lines variable has an Array(T) type which is a fixed size, so you must either allocate enough space to hold all the data or copy the data into a new construct.
If you allocated enough space for lines to hold all the data then it looks something like this:
var o = new List<string>
{
"Hist 2368#19:00:00#20:30:00#Large Conference Room",
"Hist 2368#09:00:00#10:30:00#Large Conference Room",
};
var lines = new string[3] { "Meeting#19:00:00#20:30:00#Conference", null, null };
// Copy the data from o to the end of lines
o.CopyTo(lines, 1); // Start a 1 to not overwrite the existing data
See also:
CopyTo(T[] array)
Otherwise if you have two different data sources that you want to pool into a new construct then I recommend using the Concat method. This will combine the IEnumerable(T) types which you can use ToArray or ToList to give the data the right container.
var o = new List<string>
{
"Hist 2368#19:00:00#20:30:00#Large Conference Room",
"Hist 2368#09:00:00#10:30:00#Large Conference Room",
};
var lines = new[]
{
"Meeting#19:00:00#20:30:00#Conference",
}.Concat(o).ToArray();
Be sure you know which container you want to use.
You can concatenate the values using Enumerable.Concat :
lines = O.Concat(lines).ToArray();
Simply this
lines = lines.Concat(o).ToArray();
Try this:
List<string> myList = new List<string>()
{
"My First String in List",
"My Second String in List"
};
string[] myArray = new string[] { "My Array First String" };
List<string> myArrayList = new List<string>();
foreach (var item in myArray)
{
myArrayList.Add(item);
}
foreach (var item in myList)
{
myArrayList.Add(item);
}
foreach (var item in myArrayList)
{
Console.WriteLine(item);
}
Console.Read();
How do I check whether a List contains an element that exists in another List using LINQ in C#? I don't want to use a for/while loop.
So, if List1 has A, B, C and List2 has B, 1, 2, then I would return true.
Try this:
List<string> a = ...
List<string> b = ...
var inComon = a.Intersect(b).Any();
Use Enumerable.Any Method:
List<string> l1 = new List<string> { "1", "2" };
List<string> l2 = new List<string> { "1", "3" };
var result = l2.Any(s => l1.Contains(s));
I'd say the Intersect method (see answer by dasblinkenlight) + Any must work better than Contains + Any. It is definetely better to use Any than Count.