Concatenate<T>(List<T> list, string specifiedPropertyOfT)? - c#

From Parameter to Property?
public class ConcatenateListTMember
{
public static void Test()
{
var someList = new List<AnyClass>();
someList.Add(new AnyClass("value1"));
someList.Add(new AnyClass("value2"));
Console.WriteLine(Concatenate(someList, "SomeProperty"));
Console.ReadLine();
}
static string Concatenate<T>(List<T> list, string specifiedPropertyOfT)
{
string output = String.Empty;
// TODO: Somehow concatenate all the specified property elements in the list?
return output;
}
}
internal class AnyClass
{
public AnyClass(string someProperty)
{
SomeProperty = someProperty;
}
public string SomeProperty { get; set; }
}
How might it be possible to implement the generic method in this code sample?
Please note that specifiedPropertyOfT does not have to be a string if the same aim can be achieved using another type.
Ideally, reflection would not be needed :)

I think you're looking for the new overloads of string.Join in .NET 4 which would allow:
IEnumerable<AnyClass> sequence = ...;
string joined = string.Join(",", sequence.Select(x => x.SomeProperty));
If you can't use a lambda expression to express the property - e.g. because this has to be done at execution time - then you will have to use reflection.
Note that the selector in Select doesn't have to return strings - String.Join will call ToString on any non-string values.

Even better - an extension method:
static string Concatenate<T>(this IEnumerable<T> list, Func<T,string> func)
{
return String.Join("",list.Select(func));
}
Usage:
someList.Concatenate(i => i.SomeProperty);
Live example: http://rextester.com/runcode?code=LRA78268

Try something like this. I've created an extension method on IEnumerable:
public static class Extension
{
public static string ConcatinateString<T>(this IEnumerable<T> collection, Func<T, string> GetValue)
{
StringBuilder sb = new StringBuilder();
foreach (var item in collection)
{
sb.Append(GetValue(item));
}
return sb.ToString();
}
}
Then so call it, you would use something like this:
var values = new List<TestClass>
{
new TestClass(){Name="John",Comment="Hello"},
new TestClass(){Name="Smith", Comment="Word"}
};
string s = values.ConcatinateString((x => x.Name));
string v = values.ConcatinateString((x => x.Comment));
In this example s = "JohnSmith" and v = "HelloWord". The Func() gives you flexibility. You are basically telling the function where to go to get the string to concatenate. I also used a StringBuilder in case you are working with long collections.

Related

c# return both list of string and list of generic type

I need to return multiple items from a function. How can I do that?
public List<string> GetInfo()
{
var result = new List<string>();
return result;
}
How can I return something like this? Basically List of string and maybe also a list of generic type.
public List<string> GetInfo()
{
var result = new List<string>();
return result and someType;
}
public class someType
{
public List<SomeOthertype> someOthertype { get; set; }
}
If I understand you right, you can try using named tuples:
public (List<string> result, List<SomeOthertype> other) GetInfo()
{
var result = new List<string>();
someType instance = new someType();
//TODO: put relevant code here
// we return both result and someOthertype in one tuple
return (result, instance.someOthertype);
}
Usage:
var info = GetInfo();
var result = info.result;
var other = info.other;
I would propose to use a generic method to be possible use different types:
public static (List<string>, List<U>) GetInfo<U>()
{
var list = new List<string>();
var another = new List<U>();
//...
return (list, another);
}
From c# 7 onward there are tuple value types that are the cleanest way to return multiple values from the function.
Pre c# 7 you can use out parameters

pass lambda expression as callback to an extension method and pass parameter to it

I am trying to understand the concept of lambda expression,extension method,Linq and IEnumerable interface. You can guess that i am farely new to c sharp.Here i've come up with a problem which will incorporate all the above mentioned concepts . Here i have a list which contain three object.I want to change the name property of a Students object in a specified index .I wrote an extension method which accept a callback function.Callback function accepts an integer index and a new Name string. It should change the name property and return the object .But my code failed to do so as i am not sure how to pass parameter to Func callback in extension method.I am in need of some assistant to understand the problem and fix errors from my code ?
class Program
{
static void Main(string[] args)
{
List<Students> students = new List<Students>();
students.Add(new Students(111443, "sakib"));
students.Add(new Students(111445, "zami"));
students.Add(new Students(111444, "habib"));
var student = students.First();
var changed1 = students.Change((int num,string newname) => { return students[num].s_name = newname;});
}
}
public class Students
{
public int s_id;
public string s_name;
public Students(int id, string name)
{
this.s_id = id;
this.s_name = name;
}
}
public static class LinqHelper
{
public static IEnumerable<T> Change<T> (this IEnumerable<T> source, Func<int,string,T> callback)
{
var myList = new List<Students>();
myList.Add(callback(1,"zami")); // i was passing parameter here which is not so helpful i guess !
return myList;
}
}
The Func < int, string, T > denotes a function that accepts an integer and string as inputs and T as the return type. The anonymous function you have used has a return type of "string":
var changed1 = students.Change((int num,string newname) => { return students[num].s_name = newname;});
You should return the student instance from the function to make it work. Try replacing the above code with the following:
var changed1 = students.Change((int index, string newname) =>
{
var studentObj = students[index];
studentObj.s_name = newname;
return studentObj;
});
To allow the LinqHelper to accept the index and argument, use the following:
public static class LinqHelper
{
public static IEnumerable<T> Change<T>(this IEnumerable<T> source, Func<int, string, T> callback, int index, string argument)
{
var myList = new List<T>();
myList.Add(callback(index, argument)); // i was passing parameter here which is not so helpful i guess !
return myList;
}
}
And then, you could invoke the method as follows:
var changed1 = students.Change((int index, string newname) =>
{
var studentObj = students[index];
studentObj.s_name = newname;
return studentObj;
},
1,
"zami");
You haven't created the lambda that evaluated to Func<int, string, T>. Your call to Change extension should look like:
var changed1 = students.Change((num, newnam) => {
students[num].s_name = newnam;
return students[num];
});
(you should return T as Func requires).

C# Passing an array of Func<T, List<myClass>> to a method

My first (and really horrible post) is below.
I try to do a complete example what I want to get. I hope this will be left explained a bit better.
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<Boy> boys = new List<Boy>();
boys.Add(new Boy("Jhon", 7));
boys.Add(new Boy("Oscar", 6));
boys.Add(new Boy("Oscar", 7));
boys.Add(new Boy("Peter", 5));
ClassRoom myClass = new ClassRoom(boys);
Console.WriteLine(myClass.ByName("Oscar").Count); // Prints 2
Console.WriteLine(myClass.ByYearsOld(7).Count); // Prints 2
// This has errors...................
// But this is as I would like to call my BySomeConditions method....
Console.WriteLine( // It should print 1
myClass.BySomeConditions([myClass.ByName("Oscar"),
myClass.ByYearsOld(7)]
)
);
Console.ReadKey();
}
class ClassRoom
{
private List<Boy> students;
public ClassRoom(List<Boy> students)
{
this.students = students;
}
public List<Boy> ByName(string name)
{
return students.FindAll(x => x.Name == name);
}
public List<Boy> ByYearsOld(int yearsOld)
{
return students.FindAll(x => x.YearsOld == yearsOld);
}
// This has ERRORS.......................
public List<Boy> BySomeConditions(params Func<X, List<Boy>>[] conditions)
{
IEnumerable<Boy> result = students;
foreach (var condition in conditions) {
// I want it ONLY be called with existent functions (ByName and/or ByYearsOld)
result = result.Intersect(condition(this));
}
}
}
class Boy
{
public string Name { get; set; }
public int YearsOld { get; set; }
public Boy(string name, int yearsOld)
{
Name = name;
YearsOld = yearsOld;
}
}
}
}
============== first post =====================
Hello,
I have a class with methods:
public class X
{
private readonly List<string> myList;
public X(List<string> paramList) // string is really an object
{
myList = paramList;
}
// Now I want this...
public List<string> CheckConditions(params Func<T, List<string>>[] conditions)
{
var result = myList;
foreach (Func<T, List<string>> condition in conditions)
{
result = result.Intersect(condition(T));
}
}
public List<string> check1(string S)
{
return myList.FindAll(x => x.FieldS == S);
}
public List<string> check1(int I)
{
return myList.FindAll(x => x.FieldI == I);
}
}
Sorry if there is some error, I have written from scrach to avoid complex real case.
What I want is call my methods like this:
X.check1("Jhon");
or
X.check2(12);
or (this is the goal of my question):
X.CheckConditions(X.check1("Jhon"), X.chek2(12));
Thanks and sorry by my poor example...
It is unclear where your T comes from.
Does this meet your requirements?
public class X<T>
{
private List<T> myList;
public List<T> CheckConditions(params Func<T, bool>[] conditions)
{
IEnumerable<T> query = myList;
foreach (Func<T, bool> condition in conditions)
{
query = query.Where(condition);
}
return query.ToList();
}
}
Then later:
List<T> result = X.CheckConditions(
z => z.FieldS == "Jhon",
z => z.FieldI == 12
);
You need to change the method signature of CheckConditions, it's accepting a variable number of List<string>, not functions.
public List<string> CheckConditions(params List<string>[] lists)
The return type of check1 is List<string>, so that needs to be the type of the parameter that CheckConditions accepts.
There's no reason to make it generic, you know that you want to operate on the current instance of X (so pass in this, instead of the T type parameter). You need to cleanup a few things to to get it to compile (return result and make the type of result and the Intersect call compatible). You can define it like this:
public List<string> CheckConditions(params Func<X, List<string>>[] conditions)
{
IEnumerable<string> result = myList;
foreach (var condition in conditions)
{
result = result.Intersect(condition(this));
}
return result.ToList();
}
Ant then call it like this:
xInstance.CheckConditions(x => x.check1("JHon"), x => x.check1(12));
All that said, I'm not sure why you wouldn't just pass around the results of these functions, instead of passing the actual functions around:
public List<string> CheckConditions(params List<string>[] conditions)
{
IEnumerable<string> result = myList;
foreach (var condition in conditions)
{
result = result.Intersect(condition);
}
return result.ToList();
}
Then call it as in your example, rather than passing in lambda expressions.
you could rewrite you function to look like this:
// Now I want this...
public List<string> CheckConditions(params Func<T, List<string>>[] conditions)
{
var result = myList;
foreach (Func<T, List<string>> condition in conditions)
{
result = result.Intersect(condition(T));
}
}
your call would then be X.CheckConditions(()=>X.check1("Jhon"), ()=>X.chek2(12));
and you need to provide an instance for x (since the methods are instance methods and not static methods)
In your example you pass T as an argument to the functor but T is a type argument som it can't be passed as an argument to the method. Did you mean to pass a value?
This begs for a clarification of why you would want to do this. Maybe if you provided details on what you are trying to accomplish (as opposed to how) then you could get a better solution to your problem.
What you pass to your
X.CheckConditions
is not a reference to the functions, but the returned value of their invocation.
Now, if you pass function reference - it does not come with parameters, unless you construct and pass a data-structure that will contain the function reference and the arguments it should work on.
In this case - generics is not the solution. You should consider another pattern to follow, like command pattern or strategy pattern, where you pass to your CheckConstruction instances of checker-objects, each is instantiated with the parameters it should work on, and either implements or is provided by the validation function.

Delegate as function

Below function working ok but I want to make it simple.
if (list.Exists(delegate(string s) { return s.Contains(str); }))
{
string name = list.Find(delegate(string s) { return s.Contains(str); });
}
I am using delegate(string s) { return s.Contains(str); }
two times Is there any way to make this simple.
I know how to create delegate but don't know how to use it.
//create delegate
public delegate bool nameExistsDelegate(List<string> list, string name);
// Create a method for a delegate.
public static bool IsnameExists(List<string> list, string name)
{
return list.Exists(delegate(string s) { return s.Contains(name) ; });
}
// Create a method for a delegate.
public static string GetName(List<string> list, string name)
{
return list.Find(delegate(string s) { return s.Contains(name) ; });
}
UPDATE
stuck with .NET 2.0 so I can't use LINQ
The anonymous method you're using will be converted to a Predicate<string> delegate by the compiler. With this in mind, you can introduce a local to get rid of the redundancy you don't want.
Predicate<string> containsStr = delegate(string s) { return s.Contains(str); };
if (list.Exists(containsStr))
{
string name = list.Find(containsStr);
...
}
In C# 3.0 or later, you can express this even more succintly with lambda-expressions.
Predicate<string> containsStr = s => s.Contains(str);
On another note, you don't need to first test that str exists and then proceed to find it (assuming the list doesn't contain nulls), you could just do:
string name = list.Find(s => s.Contains(str));
if(name != null)
{
//found
}
Of course, I should also point out that strings don't contain any extra meta-data other than the characters present in them, so you don't gain anything by 'finding' a string in a list over just proving it exists (unless you meantFindIndex).
if you're on .net 3.5 you can use lamdas
//create delegate
public delegate bool nameExistsDelegate(List<string> list, string name);
static Func<string, bool> exists = s => return s.Contains(name);
// Create a method for a delegate.
public static bool IsnameExists(List<string> list, string name)
{
return list.Exists(s => exists(s));
}
// Create a method for a delegate.
public static string GetName(List<string> list, string name)
{
return list.Find(s => exists(s));
}
I'd recommend reading up on the standard delegate types in C#
Here you actually need a Predicate, which takes in an object, tests it with some condition and returns a pass/fail result.
Predicate<string> containsCheck = item = > item.Contains(str);
if (list.Exists(containsCheck)
{
string name = list.Find(containsCheck);
}
Note: all of the code can also be done using LINQ, which is considerable simpler. But I guess you must be learning delegates right now.. JFYI
using System.Linq;
...
Predicate<string> substringCheck = item => item.Contains(str);
var exists = list.Any(substringCheck);
var getMatch = list.First(substringCheck);

Is it possible to cache a value evaluated in a lambda expression?

In the ContainsIngredients method in the following code, is it possible to cache the p.Ingredients value instead of explicitly referencing it several times? This is a fairly trivial example that I just cooked up for illustrative purposes, but the code I'm working on references values deep inside p eg. p.InnerObject.ExpensiveMethod().Value
edit:
I'm using the PredicateBuilder from http://www.albahari.com/nutshell/predicatebuilder.html
public class IngredientBag
{
private readonly Dictionary<string, string> _ingredients = new Dictionary<string, string>();
public void Add(string type, string name)
{
_ingredients.Add(type, name);
}
public string Get(string type)
{
return _ingredients[type];
}
public bool Contains(string type)
{
return _ingredients.ContainsKey(type);
}
}
public class Potion
{
public IngredientBag Ingredients { get; private set;}
public string Name {get; private set;}
public Potion(string name) : this(name, null)
{
}
public Potion(string name, IngredientBag ingredients)
{
Name = name;
Ingredients = ingredients;
}
public static Expression<Func<Potion, bool>>
ContainsIngredients(string ingredientType, params string[] ingredients)
{
var predicate = PredicateBuilder.False<Potion>();
// Here, I'm accessing p.Ingredients several times in one
// expression. Is there any way to cache this value and
// reference the cached value in the expression?
foreach (var ingredient in ingredients)
{
var temp = ingredient;
predicate = predicate.Or (
p => p.Ingredients != null &&
p.Ingredients.Contains(ingredientType) &&
p.Ingredients.Get(ingredientType).Contains(temp));
}
return predicate;
}
}
[STAThread]
static void Main()
{
var potions = new List<Potion>
{
new Potion("Invisibility", new IngredientBag()),
new Potion("Bonus"),
new Potion("Speed", new IngredientBag()),
new Potion("Strength", new IngredientBag()),
new Potion("Dummy Potion")
};
potions[0].Ingredients.Add("solid", "Eye of Newt");
potions[0].Ingredients.Add("liquid", "Gall of Peacock");
potions[0].Ingredients.Add("gas", "Breath of Spider");
potions[2].Ingredients.Add("solid", "Hair of Toad");
potions[2].Ingredients.Add("gas", "Peacock's anguish");
potions[3].Ingredients.Add("liquid", "Peacock Sweat");
potions[3].Ingredients.Add("gas", "Newt's aura");
var predicate = Potion.ContainsIngredients("solid", "Newt", "Toad")
.Or(Potion.ContainsIngredients("gas", "Spider", "Scorpion"));
foreach (var result in
from p in potions
where(predicate).Compile()(p)
select p)
{
Console.WriteLine(result.Name);
}
}
Have you considered Memoization?
The basic idea is this; if you have an expensive function call, there is a function which will calculate the expensive value on first call, but return a cached version thereafter. The function looks like this;
static Func<T> Remember<T>(Func<T> GetExpensiveValue)
{
bool isCached= false;
T cachedResult = default(T);
return () =>
{
if (!isCached)
{
cachedResult = GetExpensiveValue();
isCached = true;
}
return cachedResult;
};
}
This means you can write this;
// here's something that takes ages to calculate
Func<string> MyExpensiveMethod = () =>
{
System.Threading.Thread.Sleep(5000);
return "that took ages!";
};
// and heres a function call that only calculates it the once.
Func<string> CachedMethod = Remember(() => MyExpensiveMethod());
// only the first line takes five seconds;
// the second and third calls are instant.
Console.WriteLine(CachedMethod());
Console.WriteLine(CachedMethod());
Console.WriteLine(CachedMethod());
As a general strategy, it might help.
Can't you simply write your boolean expression in a separate static function which you call from your lambda - passing p.Ingredients as a parameter...
private static bool IsIngredientPresent(IngredientBag i, string ingredientType, string ingredient)
{
return i != null && i.Contains(ingredientType) && i.Get(ingredientType).Contains(ingredient);
}
public static Expression<Func<Potion, bool>>
ContainsIngredients(string ingredientType, params string[] ingredients)
{
var predicate = PredicateBuilder.False<Potion>();
// Here, I'm accessing p.Ingredients several times in one
// expression. Is there any way to cache this value and
// reference the cached value in the expression?
foreach (var ingredient in ingredients)
{
var temp = ingredient;
predicate = predicate.Or(
p => IsIngredientPresent(p.Ingredients, ingredientType, temp));
}
return predicate;
}
Well, in this case, if you can't use Memoization, you're rather restricted since you can really only use the stack as your cache: You've got no way to declare a new variable at the scope you'll need. All I can think of (and I'm not claiming it will be pretty) that will do what you want but retain the composability you need would be something like...
private static bool TestWith<T>(T cached, Func<T, bool> predicate)
{
return predicate(cached);
}
public static Expression<Func<Potion, bool>>
ContainsIngredients(string ingredientType, params string[] ingredients)
{
var predicate = PredicateBuilder.False<Potion>();
// Here, I'm accessing p.Ingredients several times in one
// expression. Is there any way to cache this value and
// reference the cached value in the expression?
foreach (var ingredient in ingredients)
{
var temp = ingredient;
predicate = predicate.Or (
p => TestWith(p.Ingredients,
i => i != null &&
i.Contains(ingredientType) &&
i.Get(ingredientType).Contains(temp));
}
return predicate;
}
You could combine together the results from multiple TestWith calls into a more complex boolean expression where required - caching the appropriate expensive value with each call - or you can nest them within the lambdas passed as the second parameter to deal with your complex deep hierarchies.
It would be quite hard to read code though and since you might be introducing a bunch more stack transitions with all the TestWith calls, whether it improves performance would depend on just how expensive your ExpensiveCall() was.
As a note, there won't be any inlining in the original example as suggested by another answer since the expression compiler doesn't do that level of optimisation as far as I know.
I would say no in this case. I assume that the compiler can figure out that it uses the p.Ingredients variable 3 times and will keep the variable closeby on the stack or the registers or whatever it uses.
Turbulent Intellect has the exactly right answer.
I just want to advise that you can strip some of the nulls and exceptions out of the types you are using to make it friendlier to use them.
public class IngredientBag
{
private Dictionary<string, string> _ingredients =
new Dictionary<string, string>();
public void Add(string type, string name)
{
_ingredients[type] = name;
}
public string Get(string type)
{
return _ingredients.ContainsKey(type) ? _ingredients[type] : null;
}
public bool Has(string type, string name)
{
return name == null ? false : this.Get(type) == name;
}
}
public Potion(string name) : this(name, new IngredientBag()) { }
Then, if you have the query parameters in this structure...
Dictionary<string, List<string>> ingredients;
You can write the query like this.
from p in Potions
where ingredients.Any(i => i.Value.Any(v => p.IngredientBag.Has(i.Key, v))
select p;
PS, why readonly?

Categories

Resources