1

I have basically achieved my desired effect through a not so elegant foreach loop. I am posting here for two reasons. One is if someone can show me a "cool" kid way to do it and or comment on reality as sometimes a foreach over an array is faster then casting to a List then using Lambda expressions.

So I am working with ExtendedAttributes property on the Artifact class. https://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.artifact(v=vs.110).aspx

//I get my array of artifacts just fine

LinkFilter linkFilter = new LinkFilter();
linkFilter.FilterType = FilterType.ToolType;
linkFilter.FilterValues = new String[1] { ToolNames.WorkItemTracking }; //only work itms

Artifact[] artifacts = linkingService.GetReferencingArtifacts(changesetArtifactUris.ToArray(), new LinkFilter[1] { linkFilter });

//now I want to keep work items that are resolved or closed
//so I cast put into a List<T> just to then use Lambda in a for each loop
//THIS SECTION PSEUDO CODE FOR BREVITY yes I know you can't modify object you are looping over
var lst_artifacts = new List<Artifact>(artifacts);
foreach (var item in lst_artifacts)
{
   lst_artifacts.RemoveAt(item.ExtendedAttributes.ElementAt(y => y.Value != "Resolved" || y.Value != "Closed"));
}

Thoughts?

GPGVM
  • 5,515
  • 10
  • 56
  • 97
  • 2
    CodeReview SE may be more appropriate for this kind of question... Note that LINQ is generally not useful for removal of items (as opposed to filter + ToList)... On other hand removal of items one-by-one is likely slower than filter and recreate list - try and measure. – Alexei Levenkov Sep 16 '15 at 01:19
  • CodeReview SE..should have known something like that would have existed but never thought to check. Thanks – GPGVM Sep 16 '15 at 01:21
  • I'd post the whole method on CR though, not just a snippet; Code Review folks like to see the full context and comment on any and all aspects of the code (that's actually in their Help Center rules for on-topicness). See you there! – Mathieu Guindon Sep 16 '15 at 01:24
  • possible duplicate: http://stackoverflow.com/questions/853526/using-linq-to-remove-elements-from-a-listt?rq=1 – Ken Hung Sep 16 '15 at 05:49
  • @KenHung The link was educational as to the wisdom of HashSets so Thank You. But my dilemma is with the nested collection being where I make my filter determination. – GPGVM Sep 16 '15 at 14:08

2 Answers2

1

Disclaimer: Not a cool kid.

What about using .Where() with a invert of your existing predicate:

authorsList = authorsList.Where(x => x.ExtendedAttributes.ElementAt(y => y.Value == "Resolved" || y.Value == "Closed")).ToList();

EDIT: Added .ToList() as I always forget it, thanks to @KyleJV

hammus
  • 2,602
  • 2
  • 19
  • 37
  • Don't forget .ToList() – Kyle J V Sep 16 '15 at 01:24
  • Thanks @KyleJV. I **always** forget It returns a generic `IEnumberable` rather than a `List` – hammus Sep 16 '15 at 01:27
  • Hold on, isn't the OP looking to remove the selected values? We probably would want opposite logic, not that two != operators on an "OR" isn't probably going to give odd results. Ex: value as "Resolved" would return true since it is not equal to "Closed" – Kyle J V Sep 16 '15 at 01:31
  • Gawd... Right again. Sometimes, I wonder if I should answer questions on this site. – hammus Sep 16 '15 at 01:34
0

It seems that you are struggling on which function to use. You should use Any() instead of ElementAt(), your lambda y => y.Value != "Resolved" || y.Value != "Closed" is not a number, you cannot pass it into ElementAt(). You can use ElementAt(1), ElementAt(2) to get the element at specific index, but not ElementAt(true).

lst_artifacts.RemoveAll(item => !item.ExtendedAttributes.Any(y => y.Value == "Resolved" || y.Value == "Closed"));

It will remove all the items which do not have any resolved or closed attributes.

Ken Hung
  • 752
  • 5
  • 13