I need to know if the List I am working with contains only some specific values.
var list = new List<string> { "First", "Second", "Third" };
If I want to know if the List contain at least one item with the value "First" I use the Any keyword:
var result = list.Any(l => l == "First");
But how I can write a Linq expression that will return true/false only if the List contains "First" and "Second" values?
I'm not entirely sure what you want, but if you want to ensure that "First" and "Second" are represented once, you can do:
var result = list.Where(l => l == "First" || l =="Second")
.Distinct()
.Count() == 2;
or:
var result = list.Contains("First") && list.Contains("Second");
If you've got a longer "whitelist", you could do:
var result = !whiteList.Except(list).Any();
On the other hand, if you want to ensure that all items in the list are from the white-list and that each item in the white-list is represented at least once, I would do:
var set = new HashSet(list);
set.SymmetricExceptWith(whiteList);
var result = !set.Any();
EDIT: Actually, Jon Skeet's SetEquals is a much better way of expressing the last bit.
Your question is unclear.
From the first sentence, I'd expect this to be what you're after:
var onlyValidValues = !list.Except(validValues).Any();
In other words: after you've stripped out the valid values, the list should be empty.
From the final sentence, I'd expect this:
var validSet = new HashSet<string>(requiredValues);
var allAndOnlyValidValues = validSet.SetEquals(candidateSequence);
Note that this will still be valid if your candidate sequence contains the same values multiple times.
If you could clarify exactly what your success criteria are, it would be easier to answer the question precisely.
You can use Intersect to find matches:
var list = new List<string> { "First", "Second", "Third" };
var comparelist = new List<string> { "First", "Second" };
var test = list.Intersect(comparelist).Distinct().Count() == comparelist.Count();
Related
I have two queries. I want to assign the list values returned from these two queries to a single list, send it to the view and meet it in the view. My goal is to learn to work with lists in C#.
var list1 = c.ETs.Where(p => p.prop != "yes").ToList();
var list2 = c.ETs.Where(p => p.prop == "yes").ToList();
You can merge two lists into one with this:
var newList = List1
.Concat(List2)
.ToList();
Though you could drop the ToList and work directly with the IEnumerable which means you don't need to create a new object.
However, this doesn't even need to be two queries since the Where clauses of both are opposite so they include the entire table, you could do:
var list = c.ETs.ToList();
Or if you want to have two different clauses that aren't simply opposites:
var list = ct.ETs
.Where(p => p.prop == "yes" || p.prop == "no")
.ToList()` for example
This will combine the values of both lists in a single list (the final output will be stored in List1):
List1.AddRange(List2);
Hi Ahmet you can try something like this but note you will need Linq:
var list3 = List1.Concat(List2).ToList();
or if you have more than 2 lists:
var list3 = list1.Concat(list2)
.Concat(list3)
.ToList();
Another method:
var list3 = List1.AddRange(List2);
Both above will create a new list containing both lists' items.
I want to build a suggestion builder where I want to display search suggestions on changing the text in TextField. I want to search on the basis of contains method but I want to sort that particular list on the basis of startsWith, If I only use startsWith it neglects all other contains, How can I apply both simultaneously?
I have a List,
List<String> list = ["apple", "orange", "aaaaorange", "bbbborange","cccccorange"]
Now If I put only ora in search it's returning me in the following order,
aaaaorange
bbbborange
cccccorange
orange
What I want.
orange
aaaaorange
bbbborange
cccccorange
Code:
return list
.where((item) {
return item.toLowerCase().contains(query.toLowerCase());
}).toList(growable: false)
..sort((a, b) {
return a.toLowerCase().compareTo(b.toLowerCase());
});
It may be easiest to think of the two queries separately, and then combine the results:
var list = <String>[
'apple',
'orange',
'aaaaorange',
'bbbborange',
'cccccorange',
];
var pattern = 'ora';
var starts = list.where((s) => s.startsWith(pattern)).toList();
var contains = list
.where((s) => s.contains(pattern) && !s.startsWith(pattern))
.toList()
..sort((a, b) => a.toLowerCase().compareTo(b.toLowerCase()));
var combined = [...starts, ...contains];
print(combined);
In C# .NET 4.0, I am struggling to come up with the most efficient way to determine if the contents of 2 lists of items contain any differences.
I don't need to know what the differences are, just true/false whether the lists are different based on my criteria.
The 2 lists I am trying to compare contain FileInfo objects, and I want to compare only the FileInfo.Name and FileInfo.LastWriteTimeUtc properties of each item. All the FileInfo items are for files located in the same directory, so the FileInfo.Name values will be unique.
To summarize, I am looking for a single Boolean result for the following criteria:
Does ListA contain any items with FileInfo.Name not in ListB?
Does ListB contain any items with FileInfo.Name not in ListA?
For items with the same FileInfo.Name in both lists, are the FileInfo.LastWriteTimeUtc values different?
Thank you,
Kyle
I would use a custom IEqualityComparer<FileInfo> for this task:
public class FileNameAndLastWriteTimeUtcComparer : IEqualityComparer<FileInfo>
{
public bool Equals(FileInfo x, FileInfo y)
{
if(Object.ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
return x.FullName.Equals(y.FullName) && x.LastWriteTimeUtc.Equals(y.LastWriteTimeUtc);
}
public int GetHashCode(FileInfo fi)
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
hash = hash * 23 + fi.FullName.GetHashCode();
hash = hash * 23 + fi.LastWriteTimeUtc.GetHashCode();
return hash;
}
}
}
Now you can use a HashSet<FileInfo> with this comparer and HashSet<T>.SetEquals:
var comparer = new FileNameAndLastWriteTimeUtcComparer();
var uniqueFiles1 = new HashSet<FileInfo>(list1, comparer);
bool anyDifferences = !uniqueFiles1.SetEquals(list2);
Note that i've used FileInfo.FullName instead of Name since names aren't unqiue at all.
Sidenote: another advantage is that you can use this comparer for many LINQ methods like GroupBy, Except, Intersect or Distinct.
This is not the most efficient way (probably ranks a 4 out of 5 in the quick-and-dirty category):
var comparableListA = ListA.Select(a =>
new { Name = a.Name, LastWrite = a.LastWriteTimeUtc, Object = a});
var comparableListB = ListB.Select(b =>
new { Name = b.Name, LastWrite = b.LastWriteTimeUtc, Object = b});
var diffList = comparableListA.Except(comparableListB);
var youHaveDiff = diffList.Any();
Explanation:
Anonymous classes are compared by property values, which is what you're looking to do, which led to my thinking of doing a LINQ projection along those lines.
P.S.
You should double check the syntax, I just rattled this off without the compiler.
I have a list,
List<bool> MyList;
MyList.Add(true);
MyList.Add(false);
MyList.Add(false);
What is a clean way to use linq to test if any value is true? I tried
MyList.Find(SomeBoolean=>SomeBoolean)
but the result is weird.
Try :
bool test = MyList.Any(x => x);
But you have to initialize your list before inserting anything.
Use Any
var anyTrue = MyList.Any(i => i);
If you want to List all the true value
List<bool> MyList = new List<bool>();
MyList.Add(true);
MyList.Add(false);
MyList.Add(false);
var listTrue = MyList.Where(c => c);
I wonder, what is your actual Class because if you want to .Find is the same result.
var b = MyList.Find(c => c)
maybe you forgot to declare the var or DataType?
myList is a list of bool
myList= getSelectedChannels();
List allTrue= myList.FindAll(a => a == true);
allTrue will be a list of bool that match the criteria (bool is true). Now just say allTrue.Count to get the number of items in that list.
I'm having a list of string like
var target = new List<string>() { "C", "C-sharp", "java" };
I'm having a string request = "C is a programming language"
This list should match with the string and should return
C,C-sharp
How can i do this?
here is the solution with linq
var m = from t in target
where t[0] == 'C'
select t;
Using Linq and String.Contains:
var filtered = target.Where(str => str.Contains("C"));
Another option, without Linq, is to change the existing list using List<T>.RemoveAll:
target.RemoveAll(str => !str.Contains("C"));
If you really need a regex (for something more complex), you may also use:
Regex validate = new Regex(".a.", RegexOptions.IgnoreCase);
var filtered = target.Where(str => validate.Match(str).Success);