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;
}
Related
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();;
}
Currently, to replace an item I'm using the following code:
var oldItem = myList.Single(x => x.Id == newItem.Id);
var pos = myList.ToList().IndexOf(oldItem);
myList.Remove(oldItem);
myList.ToList().Insert(pos, newItem);
So, I created an extension to do the same as above but using lambda expression, and I came up with this:
public static ICollection<T> Replace<T>(this IEnumerable<T> list, T oldValue, T newValue) where T : class
{
if (list == null)
throw new ArgumentNullException(nameof(list));
return list.Select(x => list.ToList().IndexOf(oldValue) != -1 ? newValue : x).ToList();
}
So I can use it as follows:
var oldItem = myList.Single(x => x.Id == newItem.Id);
myList = myList.Replace(oldItem, newItem);
However, it's not working. What am I missing?
While you can't replace the item in the materialized collection itself, you can replace the item that is yielded from a different IEnumerable<T> at a certain position.
All you have to do is use the Select extension method on IEnumerable<T> to map to the new item when the Id property matches, and use the new IEnumerable<T> instance, like so:
// Assuming newItem is already defined, has the value you want to yield
// and T is the type of newItem
IEnumerable<T> newEnumerable = myList.Select(i =>
i.Id == newItem.Id ? newItem : i
);
Then, when you iterate through the newEnumerable, when the item in the old list has an Id equal to newItem.Id, it will yield newItem.
IEnumerable is for traversing a generic data structure. Think about it as read-only access. In fact, making modifications to the IEnumerable while enumerating it is a big NO NO. Your original solution is fine, except for the last line. Just do Remove and Insert.
You're going to have a hard time doing this with IEnumerable as that interface is designed for iterating. However, you can get things working with IList
public static IList<T> Replace<T>(IList<T> list, T oldValue, T newValue) where T : class
{
var pos = list.IndexOf(oldValue);
list.Remove(oldValue);
list.Insert(pos, newValue);
return list;
}
With test code of
static void Main(string[] args)
{
IList<Item> myList = new List<Item>() { new Item { Id = "123" }, new Item { Id = "abc" }, new Item { Id = "XYZ" } };
var newItem = new Item { Id = "abc" };
var oldItem = myList.Single(x => x.Id == newItem.Id);
myList = Replace(myList, oldItem, newItem);
}
For an obvious definition of Item
class Item
{
public string Id { get; set; }
public readonly Guid Guid = Guid.NewGuid();
}
Since your sample code shows the use of ToList(), maybe creating a new collection (rather than modifying an existing one) is fine. If that's the case, you would write your Replace() method as follows
public static ICollection<T> Replace<T>(IEnumerable<T> list, T oldValue, T newValue) where T : class
{
var l = list.ToList();
var pos = l.IndexOf(oldValue);
l.Remove(oldValue);
l.Insert(pos, newValue);
return l;
}
This method works, except it returns List<object> when what I really want is List<Resource> when specificType is Resource (and List<YYY> when specificType is YYY, and so on).
How can I rearrange the method signature to return List<specificType>? Then, is there a better way to do this? The items in List<object> are deserialized from many different types in this assembly. I'm trying to create lists of ActualType and return that list to caller. Hope this makes sense.
private static ICollection<object> GetSpecificTypeList(Dictionary<string, List<object>> objectListDictionary, Type specificType)
{
Contract.Requires(objectListDictionary != null);
Contract.Requires(specificType != null);
var typeFullName = specificType.FullName;
var typedCollection = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(specificType));
var collection = objectListDictionary.SingleOrDefault(q => q.Key.Equals(typeFullName)).Value;
foreach (var obj in collection)
{
typedCollection.Add(Convert.ChangeType(obj, specificType));
}
return collection;
}
var resourceList = GetSpecificTypeList(package.FilesDictionary, typeof(Resource));
Would dynamic help?
Make the method generic:
private static ICollection<T> GetSpecificTypeList<T>(Dictionary<string, List<object>> objectListDictionary)
{
Contract.Requires(objectListDictionary != null);
Contract.Requires(specificType != null);
var list = new List<T>();
var collection = objectListDictionary.SingleOrDefault(q => q.Key.Equals(typeof(T).FullName)).Value;
foreach (var obj in collection.OfType<T>())
{
list.Add(obj);
}
return list;
}
How can I rearrange the method signature to return List<specificType>?
Make the method generic:
private static ICollection<T> GetSpecificTypeList<T>(Dictionary<string, List<object>> objectListDictionary)
{
Contract.Requires(objectListDictionary != null);
Contract.Requires(specificType != null);
var typeFullName = typeof(T).FullName;
//var collection = objectListDictionary.SingleOrDefault(q => q.Key.Equals(typeFullName)).Value;
var collection = objectListDictionary[typeFullName];
var typedCollection = collection.OfType<T>().ToList();
return typedCollection;
}
Now your calling syntax is:
var resourceList = GetSpecificTypeList<Resource>(package.FilesDictionary);
A few other suggestions:
Consider a Dictionary<Type, List<object> instead - using s atring to identify a type can be tricky
You may even be able to use List<object> and filter using list.OfType<T> (assuming that the key for each object collection is its type.
Here is my modified version of Dave's propsal using yield return and IEnumerable, which enables lazy evaluation:
private static IEnumerable<T> GetSpecificTypeList<T>(Dictionary<string, List<object>> objectListDictionary)
{
Contract.Requires(objectListDictionary != null);
var collection = objectListDictionary.SingleOrDefault(q => q.Key.Equals(typeof(T).ToString())).Value;
foreach (var obj in collection)
{
yield return (T) Convert.ChangeType(obj, typeof(T));
}
}
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())
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.