I have a list of objects, called Attributes, that, essentially, i need to do the following in C#
<pseudocode>
if (list.Contains(Attribute where getName() == "owner"))
{
do stuff
}
</pseudocode>
the problem I'm having is the nested bracket bit of the if - "Attribute where getName() == "owner". This is my code - it doesn't work, obviously, but most of the if should be right, it's just getting that i need to do the bit in forward slashes and i don't know how.
if (attributes.Contains(Attribute /where/ attribute.getName() == "Owner"))
{
string value = attr.getValue();
value = value.Replace(domain, "");
user = value;
UserExists(value);
}
I'm probably being dense, but I had to restart 3 days development to change everything to using Attribute objects, so my brain is rather destroyed. Sorry.
If you are using a version of .NET that supports LINQ (3.5 or higher), try
if(attributes.Any(attribute=>attribute.getName()=="Owner"))
{
do stuff
}
This has the nice advantage of being fairly readable by whoever has to maintain this code.
if(list.Exists(e=>e.getName() == "owner")) {
//yup
}
You can use LINQ to objects
if (attributes.Count(a => a.getName() == "Owner") > 0)
Without LINQ!:
if (list.Exists(delegate(Attribute a) { return a.GetName() == "Owner"; }))
Please have a look:
var filteredAttributes = from attribute in Attributes
where string.Compare(attribute.getName() ,"Owner",true)==0
select attribute;
foreach(var attribute in filteredAttributes)
{
string value = attr.getValue();
value = value.Replace(domain, "");
user = value;
UserExists(value);
}
You can use LINQ to separate out the required attributes...
IEnumerable<TAttribute> ownerAttributes =
attributes.Where(attribute => attribute.getName() == "Owner");
... and then iterate over those attributes, applying the relevant logic...
foreach(TAttribute attribute in ownerAttributes)
{
// Do stuff...
}
are you using .NET 3.5 or above, if so and presuming that 'attributes' is derived from IEnumerable, you could do the following :
if (attributes.Any(attrib=>attrib.GetName() == "Owner"))
{
//Do code here...
}
Ok, i worked it out, I found a much better way to do it:
for (int i = 0; i < attributes.Count; i++)
{
if (attributes[i].getName() == "Owner")
{
string value = attributes[i].getValue();
value = value.Replace(domain, "");
user = value;
UserExists(value);
}
}
which makes more sense, and actually works.
Related
I believe its not a hard one, but could not found anything.
I have a List of objects and i would like to write a query to determine if a specific property of all the objects has the value of 1 or not.
I would like to do that using LINQ \ Lambda.
private bool IsTheSame(List<ContenderLeague> TryUpgradeConts)
{
bool IsTheSameValue = true;
foreach (ContenderLeague c in TryUpgradeConts)
{
if (c.Contender.Factor != 1)
{
IsTheSameValue = false;
break;
}
}
return IsTheSameValue;
}
using System.Linq; // at the top of your code file
Altered code
var allHaveContederFactorValueOne = TryUpgradeConts.All(i => i.Contender.Factor == 1);
Learn how to use lambdas expressions and the various built in functions in the framework like All, Any, Where, etc. They make coding much easier.
What you describe is using All extension method as you can see in the other answers:
return TryUpgradeConts.All(c=>c.Contender.Factor == 1);
But the real translation of your code is using Any:
return TryUpgradeConts.Any(c=>c.Contender.Factor != 1);
You are trying to find some element which doesn't meet the condition
Use the linq .All() method. Something like below should work.
private bool IsTheSame(List<ContenderLeague> TryUpgradeConts)
{
return TryUpgradeConts.All(c => c.Contender.Factor == 1);
}
I'm trying to figure out if a property is an auto property i.e.
public int Foo { get; set; }
Stared for a while at PropertyDeclarationSyntax and IPropertySymbol but did not find anything.
Guess an alternative is an extension method that evaluates if get & set does not contain any statements is one way but it does not feel very elegant.
Check whether any of the AccessorDeclarationSyntaxes in the PropertyDeclarationSyntax's AccessorList have a non-null Body.
You can see this by looking at any property declaration using the Syntax Visualizer (from the Roslyn SDK extension).
This blog gives a good explanation:
In summary,
var isExplicitProperty = node
.DescendantNodesAndSelf()
.OfType<PropertyDeclarationSyntax>()
.Any(prop =>
{
if(prop.AccessorList != null)
{
return prop.AccessorList.Accessors
.Any(a => a.Body != null || a.ExpressionBody != null);
}
// readonly arrow property declaration
return true;
});
Based on the internal source code
I am having a bit following the "a method should only do one thing"
I have a car text file, and if it contains even one BMW I want to set isValid to true, but while I am going through the text file anyways I thought I would also populate two list high end models(M3,M5 etc) and lower model (335, X3 etc).
I know that method should only do one thing, but it seems so convenient for it to also populate the lists. Here is what I have:
private bool hasBMWegments()
{
foreach (ClassLib.CarSegment carElement in CarSegmentFactory.ContainsCar("BMW"))
{
isValid = true;
if (carElement.Class.IndexOfAny(lowerModels) == 0)
{
lstOlderSegment.Add(carElement.ElementNumber);
}
if (carElementClass.IndexOfAny(upperModels) == 0)
{
lstNewerSegment.Add(carElement.ElementNumber);
}
}
return isValid;
}
Should I just create a method that performs the foreach check again? Or should I create another method inside that method (I would think that would be messy, and wouldn't related to the method name)
edit: sorry working with framework 2.0
I find that code to be a mess compared to this:
private IEnumerable<ClassLib.CarSegment>
GetModels(IEnumerable<ClassLib.CarSegment> segments, string modelID)
{
return segments.Where(x => x.Class.IndexOfAny(modelID) == 0);
}
// ...
var bmwSegments = CarSegmentFactory.ContainsCar("BMW").ToArray();
bool isValid = bmwSegments.Any();
var olderModelSegments = GetModels(bmwSegments, lowerModels);
var newerModelSegments = GetModels(bmwSegments, upperModels);
This code is obviously correct at a glance. The other code makes you look twice at the loop to figure out what's going on.
It looks like all you're doing is setting isValid to true on the first pass through the foreach. So all isValid really means is "is there at least one element?".
In which case you do not need to iterate twice. You can use Any() to do the valid check:
bool IsValid(IEnumerable<CarSegment> elements)
{
return elements.Any();
}
void PopulateSegments(IEnumerable<CarSegment> elements)
{
foreach(var element in elements)
{
//add to lists
}
}
I've posted a code sample below. Firstly let me explain
termStore.Groups in the code below is a collection of Group Objects (The exact class is irrelevant).
Checking for null : if (termStore.Groups[groupName] == null) seems like a logical (clean) approach, but if the Groups collection is empty then an exception is produced.
using the termStore.Groups.Contains is not an option either because this expects a strong type i.e: .Contains(Group)... not .Contains(GroupName as string)
Can someone recommend a clean / generic way I can check for if an item exists in collection .
Thank you....
TermStore termStore = session.TermStores.Where(ts => ts.Name == termStoreName).FirstOrDefault();
if (termStore.Groups[groupName] == null)
{
termStore.CreateGroup(groupName);
termStore.CommitAll();
}
Update: The exact class Sharepoint Taxonomy Classes. http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.taxonomy.group.aspx
Update 2, the exact collection : http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.taxonomy.groupcollection.aspx
Microsoft.SharePoint.Taxonomy.GroupCollection implements IEnumerable<Group>, so a bit of LINQ is probably just what the doctor ordered:-
if(termStore.Groups.Any(x => x.Name == "MyGroup"))
{
// group contains at least one item matching the predicate.
}
else
{
// group contains no items matching the predicate.
}
You'll need to be using .NET 3.5 or better and add "using System.Linq;" to the top of your file.
Edit
If you don't have LINQ available, or if it offends you, or if you've genuinely profiled and found that iterating over Groups is killing performance compared to the string indexer, you could use GroupCollection.Count to avoid the error state:-
if (termStore.Groups.Count == 0 || termStore.Groups[groupName] == null)
{
// Group doesn't exist.
}
IEnumerable.Any(...) should work for your case:
termsStore.Groups.Any()
I think this is what you are looking for:
termStore.Groups.ContainsKey(groupName)
Checks that the key exists, doesn't throw an exception if it doesn't. This is assuming that Groups is a collection that implements IDictionary.
May be this
termStore.Any() && termStore.Groups.Any() && termStore.Groups[groupName] == null
Ok, 2nd attempt. If Groups doesn't contain the required ContainsKey method then you can write it yourself. Then you can just use ContainsKey in place of Contains.
static class GroupExtensions
{
public static bool ContainsKey(this Groups groups, string key)
{
try
{
if(groups[key] == null)
{
return false;
}
}
catch
{
return false;
}
return true;
}
}
I have a generic list.
Some elements of this list belong to a parent element. I retrieved all these elements from a database and i want to recursively build a tree with them.
So, here's what i'm thinking:
Here is my predicate:
public static bool FindChildren(Int32 parentId,CategoryMapping catMapping)
{
if (catMapping.parentId == parentId)
{
return true;
}
else
{
return false;
}
}
root = list[0];
root.childrenElements = root.FindAll(FindChildren(root.id,???)
I can't figure out how this would work. How can i do this kind of predicate?
PS: I'm using VS2005 :(
Try
root.childrenElements =
root
.Where( i => i.parentId == yourCatMapping.parentId)
.ToArray();
EDIT
In .net 2.0 I think it is
root.FindAll(
delegate(CategoryMapping mapping)
{
return mapping.parentId == root.Id;
});
You need to specify a delegate to pass to FindAll, rather than a direct function call
(assuming root is List<CategoryMapping>)
root.childrenElements = root.FindAll(c => FindChildren(root.id, c));
You should check out this thread that I started on Forming good predicate delegates to Find() or FindAll() in a List for C# / .NET 2.0
It answers your question pretty clearly.
Gregoire's answer is the best, because it:
Doesn't use LINQ (the asker is using VS 2005)
Doesn't use a lambda expression (again, VS 2005)
That said, why not make things (slightly) easier for yourself by writing a function to generate your Predicate for you:
public static Predicate<CategoryMapping> GetIsChildOf(int parentId) {
return delegate(CategoryMapping cm) {
return cm.parentId == parentId;
};
}
Then if you have a List<CategoryMapping> and you want to find all elements with a certain parentId property, you can just call:
root = list[0];
root.childrenElements = list.FindAll(GetIsChildOf(root.id));