Refactor to generic method with Predicate<T> and inner condition variable - c#

Consider removing duplicated elements of List from a specific class like below:
private List<MyClass> RemoveDuplicatedMyClass(List<MyClass> myObjects)
{
List<MyClass> uniqueMyClasses = new List<MyClass>();
foreach (MyClass item in myObjects)
{
if (uniqueMyClasses.FindAll(itm => itm.myAttribute == item.myAttribute).Count == 0)
{
uniqueMyClasses.Add(item);
}
}
return uniqueMyClasses;
}
I want to refactor RemoveDuplicatedMyClass to a generic version RemoveDuplicatedItems like below:
public static List<T> RemoveDuplicatedItems<T>(List<T> items, Predicate<T> match)
{
if (items == null)
{
return new List<T>();
}
List<T> uniqueItems = new List<T>();
foreach (T item in items)
{
// Check if item exists (= already added)! If not add to unique list.
if (uniqueItems.FindAll(match).Count < 1)
{
uniqueItems.Add(item);
}
}
return uniqueItems;
}
Problem: How can I get access to Predicate<T> match with the inner T item?

As guys mentioned in comments, it's a good idea to use Enumerable.DistinctBy and one solution is to use dynamic objects:
static List<dynamic> RemoveDuplicatedItems(List<dynamic>? items)
{
if (items == null)
{
return new List<dynamic>();
}
return items.DistinctBy(x=>x.MyAttribute).ToList();
}
and another and I think better option is to use abstraction, if you have some common properties between your classes you can create interface and define type of T as inheritor of that interface:
static List<T> RemoveDuplicatedItems<T>(List<T>? items) where T:ISomeCommonInterface
{
if (items == null)
{
return new List<T>();
}
return items.DistinctBy(x=>x.MyAttribute).ToList();;
}

Related

How to add the IEnumerable collection to ICollection list?

I add the method for adding Ienumerable collection to Icollection.
public static ICollection<T> AddTo<T>(this IEnumerable<T> list,ICollection<T> collection) {
foreach (T item in list) {
collection.Add(item);
}
return collection;
}
But at first time initialized collection variable as null.Then i am getting "Object reference not found error"please tell me how to add Ienumerable list data to Icollection properly?
EDIT:
ICollection<UserInApplication> userInAppRole=null;
IEnumerable<UserInApplication> result=null;
result = _userService.UserInApplicationRoles(iAppRoleId, collection["displayName"]).AsEnumerable();
userInAppRole = Extensions.AddTo<UserInApplicationRole>(result,userInAppRole);
You are not initializing your collection. And extension methods can be called in a better way.
ICollection<UserInApplication> userInAppRole=new Collection<UserInApplication>(); //Initialize this
IEnumerable<UserInApplication> result=null;
result = _userService.UserInApplicationRoles(iAppRoleId,collection["displayName"])
.AsEnumerable();
userInAppRole = result.AddTo(userInAppRole);
Look at this code:
ICollection<UserInApplication> userInAppRole=null;
IEnumerable<UserInApplication> result=null;
result = _userService.UserInApplicationRoles(iAppRoleId, collection["displayName"]).AsEnumerable();
userInAppRole = Extensions.AddTo<UserInApplicationRole>(result,userInAppRole)
You're never instantiating a collection in the userInAppRole variable; it's null. When you try to add result into a null, you get an exception.
public static ICollection<T> AddTo<T>(this IEnumerable<T> list,ICollection<T> collection) {
if ((null != list) || (null != collection)) {
foreach (T item in list) {
collection.Add(item);
}
}
return collection;
}

Logical reduction of recursive enumeration

I find myself regularly writing recursive IEnumerable<T> iterators to implement the same "Descendants" pattern as provided by, for example, XContainer.Descendants. The pattern I keep implementing is as follows, given a type Foo with a single-level iterator called Children:
public static IEnumerable<Foo> Descendants(this Foo root) {
foreach (var child in root.Children()) {
yield return child;
foreach (var subchild in child.Descendants()) {
yield return subchild;
}
}
}
This old StackOverflow question suggests the same pattern. But for some reason it feels weird to me to have to reference three levels of heirarchy (root, child, and subchild). Can this fundamental depth-first recursion pattern be further reduced? Or is this an algorithmic primitive of sorts?
The best I can come up with is to abstract the pattern to a generic extension. This doesn't reduce the logic of the iterator pattern presented above, but it does remove the requirement of defining a Descendants method for multiple specific classes. On the downside, this adds an extension method to Object itself, which is a little smelly:
public static IEnumerable<T> SelectRecurse<T>(
this T root, Func<T, IEnumerable<T>> enumerator) {
foreach (T item in enumerator(root))
{
yield return item;
foreach (T subitem in item.SelectRecurse(enumerator))
{
yield return subitem;
}
}
}
// Now we can just write:
foreach(var item in foo.SelectRecurse(f => f.Children())) { /* do stuff */ }
You can use an explicit stack, rather than implicitly using the thread's call stack, to store the data that you are using. This can even be generalized to a Traverse method that just accepts a delegate to represent the "get my children" call:
public static IEnumerable<T> Traverse<T>(
this IEnumerable<T> source
, Func<T, IEnumerable<T>> childrenSelector)
{
var stack = new Stack<T>(source);
while (stack.Any())
{
var next = stack.Pop();
yield return next;
foreach (var child in childrenSelector(next))
stack.Push(child);
}
}
Because this isn't recursive, and thus isn't creating the state machines constantly, it will perform quite a bit better.
Side note, if you want a Breath First Search just use a Queue instead of a Stack. If you want a Best First Search use a priority queue.
To ensure that siblings are returned in the same order as they are returned from the selecor's order, rather than the reverse, just add a Reverse call to the result of childrenSelector.
I think this is a good question. The best explanation I have for why you need two loops: We need to recognize the fact that each item is converted to become multiple items (itself, and all its descendants). This means that we do not map one-to-one (like Select) but one-to-many (SelectMany).
We could write it like this:
public static IEnumerable<Foo> Descendants(this IEnumerable<Foo> items) {
foreach (var item in items) {
yield return item;
foreach (var subitem in item.Children().Descendants())
yield return subitem;
}
}
Or like this:
public static IEnumerable<Foo> Descendants(Foo root) {
var children = root.Children();
var subchildren = children.SelectMany(c => c.Descendants());
return children.Concat(subchildren);
}
Or like this:
public static IEnumerable<Foo> Descendants(this IEnumerable<Foo> items) {
var children = items.SelectMany(c => c.Descendants());
return items.Concat(children);
}
The versions taking an IEnumerable<Foo> must be invoked on root.Children().
I think all of these rewrites expose a different way of looking at the problem. On the other hand, they all have two nested loops. The loops can be hidden in helper functions but they still exist.
I would manage this with a List:
public static IEnumerable<Foo> Descendants(this Foo root) {
List<Foo> todo = new List<Foo>();
todo.AddRange(root.Children());
while(todo.Count > 0)
{
var first = todo[0];
todo.RemoveAt(0);
todo.InsertRange(0,first.Children());
yield return first;
}
}
Not recursive, so shouldn't blow the stack. You just always add more work for yourself onto the front of the list and so you achieve the depth-first traversal.
Both Damien_the_Unbeliever and Servy have presented versions of an algorithm that avoid creating a recursive call stack by using collections of one type or another. Damien's use of a List could cause poor performance to inserts at the head of the list, while Servy's use a of stack will cause nested elements to be returned in reverse order. I believe manually implementing a one-way linked list will maintain Servy's performance while still returning all the items in the original order. The only tricky part is initializing the first ForwardLinks by iterating the root. To keep Traverse clean I moved that to a constructor on ForwardLink.
public static IEnumerable<T> Traverse<T>(
this T root,
Func<T, IEnumerable<T>> childrenSelector) {
var head = new ForwardLink<T>(childrenSelector(root));
if (head.Value == null) yield break; // No items from root iterator
while (head != null)
{
var headValue = head.Value;
var localTail = head;
var second = head.Next;
// Insert new elements immediately behind head.
foreach (var child in childrenSelector(headValue))
localTail = localTail.Append(child);
// Splice on the old tail, if there was one
if (second != null) localTail.Next = second;
// Pop the head
yield return headValue;
head = head.Next;
}
}
public class ForwardLink<T> {
public T Value { get; private set; }
public ForwardLink<T> Next { get; set; }
public ForwardLink(T value) { Value = value; }
public ForwardLink(IEnumerable<T> values) {
bool firstElement = true;
ForwardLink<T> tail = null;
foreach (T item in values)
{
if (firstElement)
{
Value = item;
firstElement = false;
tail = this;
}
else
{
tail = tail.Append(item);
}
}
}
public ForwardLink<T> Append(T value) {
return Next = new ForwardLink<T>(value);
}
}
I propose a different version, without using yield:
public abstract class RecursiveEnumerator : IEnumerator {
public RecursiveEnumerator(ICollection collection) {
this.collection = collection;
this.enumerator = collection.GetEnumerator();
}
protected abstract ICollection GetChildCollection(object item);
public bool MoveNext() {
if (enumerator.Current != null) {
ICollection child_collection = GetChildCollection(enumerator.Current);
if (child_collection != null && child_collection.Count > 0) {
stack.Push(enumerator);
enumerator = child_collection.GetEnumerator();
}
}
while (!enumerator.MoveNext()) {
if (stack.Count == 0) return false;
enumerator = stack.Pop();
}
return true;
}
public virtual void Dispose() { }
public object Current { get { return enumerator.Current; } }
public void Reset() {
stack.Clear();
enumerator = collection.GetEnumerator();
}
private IEnumerator enumerator;
private Stack<IEnumerator> stack = new Stack<IEnumerator>();
private ICollection collection;
}
Usage example
public class RecursiveControlEnumerator : RecursiveEnumerator, IEnumerator {
public RecursiveControlEnumerator(Control.ControlCollection controlCollection)
: base(controlCollection) { }
protected override ICollection GetChildCollection(object c) {
return (c as Control).Controls;
}
}
To expand on my comment, this should work:
public static IEnumerable<Foo> Descendants(this Foo node)
{
yield return node; // return branch nodes
foreach (var child in node.Children())
foreach (var c2 in child.Descendants())
yield return c2; // return leaf nodes
}
That should will return all branch nodes and leaf nodes. If you only want to return leaf nodes, remove the first yield return.
In response to your question, yes it is an algorithmic primitive, because you definitely need to call node.Children(), and you definitely need to call child.Descendants() on each child. I agree that it seems odd having two "foreach" loops, but the second one is actually just continuing the overall enumeration, not iterating the children.
Try this:
private static IEnumerable<T> Descendants<T>(
this IEnumerable<T> children, Func<T, IEnumerable<T>> enumerator)
{
Func<T, IEnumerable<T>> getDescendants =
child => enumerator(child).Descendants(enumerator);
Func<T, IEnumerable<T>> getChildWithDescendants =
child => new[] { child }.Concat(getDescendants(child));
return children.SelectMany(getChildWithDescendants);
}
Or if you prefer the non Linq variant:
private static IEnumerable<T> Descendants<T>(
this IEnumerable<T> children, Func<T, IEnumerable<T>> enumerator)
{
foreach (var child in children)
{
yield return child;
var descendants = enumerator(child).Descendants(enumerator);
foreach (var descendant in descendants)
{
yield return descendant;
}
}
}
And call it like:
root.Children().Descendants(f => f.Children())

"Else" equivalent in foreach loop when ienumerable is empty

Assuming the ienumerable is not null, a foreach loop simply won't execute if that ienumerable is empty. But instead, I need to run other code if the collection is empty. Here's sample code which works flawlessly:
List<string> theList = new List<string>() {};
if (theList.Count > 0) {
foreach (var item in theList) {
//do stuff
}
} else {
//throw exception or do whatever else
}
Is there anyway to shorten this up via out-of-the-box C#, an Extension Method, etc? In my head I was thinking the following would be cool, but obviously it doesn't work:
List<string> theList = new List<string>() {};
foreach (var item in theList) {
//do stuff
} else {
//throw exception or do whatever else
}
EDIT: My solution thanks to insight from Maarten: The following will throw an exception if the collection is null or empty (if you want to simply ignore cases where the collection is null or empty, use a ternary operator in the foreach)
static class Extension {
public static IEnumerable<T> FailIfNullOrEmpty<T>(this IEnumerable<T> collection) {
if (collection == null || !collection.Any())
throw new Exception("Collection is null or empty");
return collection;
}
}
class Program {
List<string> theList = new List<string>() { "a" };
foreach (var item in theList.FailIfNullOrEmpty()) {
//do stuff
}
}
If you really wanted to achieve this, you could create an extension method (like you said yourself).
class Program {
static void Main(string[] args) {
List<string> data = new List<string>();
foreach (var item in data.FailIfEmpty(new Exception("List is empty"))) {
// do stuff
}
}
}
public static class Extensions {
public static IEnumerable<T> FailIfEmpty<T>(this IEnumerable<T> collection, Exception exception) {
if (!collection.Any()) {
throw exception;
}
return collection;
}
}
You can throw the exception beforehand, without having to write the else block:
if(mylist.Count == 0)
throw new Exception("Test");
foreach(var currItem in mylist)
currItem.DoStuff();
The execution flow won't reach the loop if the exception has been raised.

Edit List contains objects which themselves contain objects, and so on

I have a problem with a List of objects ...
This List contains objects which themselves contain objects, and so on ... (all objects are of the same type)
My objects looks like that :
public class MyObject (...)
{
...
public MyObject[] Object;
...
}
I'd like to change some variables of these objects (according to certain parameters), and to do that I think using LINQ.
My problem is that I do not really know how to do something that will pass through ALL my recursive List, regardless of their level.
I hope I was as clear as possible.
Thank you in advance for your help.
You can write a simple recursive method to do what you want easily enough:
public static void Touch(MyObject obj, string otherParameter)
{
obj.Value = otherParameter;
foreach (var child in obj.Object)
{
Touch(child, otherParameter);
}
}
If you really, really want a more LINQ-esque method, or you do this often enough to need a more generic approach, you could use something like this:
public static IEnumerable<T> FlattenTree<T>(IEnumerable<T> source, Func<T, IEnumerable<T>> selector)
{
//you could change this to a Queue or any other data structure
//to change the type of traversal from depth first to breath first or whatever
var stack = new Stack<T>();
while (stack.Any())
{
T next = stack.Pop();
yield return next;
foreach (T child in selector(next))
stack.Push(child);
}
}
You could then use it like:
MyObject root = new MyObject();
var allNodes = FlattenTree(new[] { root }, node => node.Object);
foreach (var node in allNodes)
{
node.Value = "value";
}
You could use this recursive extension method:
public static IEnumerable<T> Traverse<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> fnRecurse)
{
foreach (T item in source)
{
yield return item;
IEnumerable<T> seqRecurse = fnRecurse(item);
if (seqRecurse != null)
{
foreach (T itemRecurse in Traverse(seqRecurse, fnRecurse))
{
yield return itemRecurse;
}
}
}
}
You can use it in this way:
var allObj = list.Traverse(o => o.Object);
foreach (MyObject o in allObj)
{
// do something
}
It's handy because it's generic and works with any type and also because it's using deferred execution.
Maybe simply something like this:
static void AddRecursively(MyObject obj, List<MyObject> listToAddTo)
{
listToAddTo.Add(obj);
foreach (var o in obj.Object)
AddRecursively(o, listToAddTo);
}
I suggest to use this extension method that applies an action to all the items recursively
public static void ForEach<T>(this IEnumerable<T> source,
Func<T, IEnumerable<T>> getChildren,
Action<T> action)
{
if (source == null) {
return;
}
foreach (T item in source) {
action(item);
IEnumerable<T> children = getChildren(item);
children.ForEach(getChildren, action);
}
}
You would apply it to your list like this
myObjectList.ForEach(x => x.Object, x => x.Value = "new value");
The first paramter tells ForEach how to access the nested objects. The second parameter tells what to do with each item.

C# is there a foreach oneliner available?

I just want to know if there is a foreach oneliner in C#, like the if oneliner (exp) ? then : else.
If you're dealing with an array then you can use the built-in static ForEach method:
Array.ForEach(yourArray, x => Console.WriteLine(x));
If you're dealing with a List<T> then you can use the built-in ForEach instance method:
yourList.ForEach(x => Console.WriteLine(x));
There's nothing built-in that'll work against any arbitrary IEnumerable<T> sequence, but it's easy enough to roll your own extension method if you feel that you need it:
yourSequence.ForEach(x => Console.WriteLine(x));
// ...
public static class EnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
if (source == null) throw new ArgumentNullException("source");
if (action == null) throw new ArgumentNullException("action");
foreach (T item in source)
{
action(item);
}
}
}
List.ForEach Method
Imagine you have three variables and you want to set the same property of them all in only one go:
foreach (var item in new [] {labelA, labelB, labelC})
{
item.Property= Value;
}
It is the equivalent of doing:
foreach (var item in new List<SomeType>(){labelA, labelB, labelC})
{
item.Property= Value;
}
foreach line-liners could be achieved with LINQ extension methods. For example:
instead of:
var result = new List<string>();
foreach (var item in someCollection)
{
result.Add(item.Title);
}
you could:
var result = someCollection.Select(x => x.Title).ToList();
Sure, you can use something like List<>.ForEach:
List<String> s = new List<string>();
s.Add("This");
s.Add("Is");
s.Add("Some");
s.Add("Data");
s.ForEach(_string => Console.WriteLine(_string));
The primary difference between if and the ?operator is that if is a statement, while ? produces an expression. I.e. you can do this:
var _ = (exp) ? then : else; // ok
but not this:
var _ = if (exp) { then; } else { else; }; // error
So if you are looking for something like a foreach expression, there is no .NET type that can naturally return except for void, but there are no values of void type, so you can equally just write:
foreach (var item in collection) process(item);
In many functional languages, a Unit type is used instead of void which is a type with only one value. You can emulate this in .NET and create your own foreach expression:
class Unit
{
public override bool Equals(object obj)
{
return true;
}
public override int GetHashCode()
{
return 0;
}
}
public static class EnumerableEx
{
public static Unit ForEach<TSource>(
this IEnumerable<TSource> source,
Action<TSource> action)
{
foreach (var item in source)
{
action(item);
}
return new Unit();
}
}
However there hardly exists any use-case for such expressions.

Categories