8

So when you get back an list, one value is filled by the repository but the other you want to have the same value for each item in the list. It feels like an for each loop is the a lot of code for simple functionality. Is there a way to shorten the code.

So some context. This is an example class.

public class ExampleClass
{
    public string A { get; set; }
    public string B { get; set;
}

This is an method that works:

public IEnumerable<ExampleClass> GetAll(string bValue)
{
    var exampleList = repo.GetAll(); //Asume that the repo gives back the an list with A filled;
    var returnValue = new List<ExampleClass>();
    foreach (var item in exampleList)
    {
        item.B= bValue;
        returnValue.Add(item);
    }
    return returnValue;
}

It would be great if there could something like:

public IEnumerable<ExampleClass> GetAll(string bValue)
{
    return repo.GetAll().Map(i => i.B = bValue);
}

Does anyone knows something like this.

C. Molendijk
  • 2,614
  • 3
  • 26
  • 35
  • Just some looking at my code right now I can do something like this. `var allImages = new List(); allImages.ForEach(new Action((FileInfo data)=> { }));` – Bailey Miller Sep 25 '17 at 18:02
  • Really the map function is just running a for each loop inside of of a function called map that is excepting a func – Bailey Miller Sep 25 '17 at 18:04
  • You can have a Generic Function in which you can point to a property, and have it dynamically build an expression to set the property to a value – johnny 5 Sep 25 '17 at 18:05
  • 4
    Why do you need a function to do this. `repo.GetAll().ToList().ForEach(x => x.B = bValue)` I'm only using to list so I don't have to write another extension method but you get the point – johnny 5 Sep 25 '17 at 18:07
  • @BaileyMiller Yes. the map function would be syntactic sugar just to keep the main function clean. But indeed, the ForEach loop does the trick. – C. Molendijk Sep 25 '17 at 18:07
  • I have an idea that has started but I have never written a method like this before. Simply re-create what other methods do with Func. For example `.Where(x=>x==1)` is a method that accepts a Func and returns a new list. So write a map function that accepts a Func that returns a new list after executing the desired values on it. – Bailey Miller Sep 25 '17 at 18:20

4 Answers4

9

You could use yield return:

public IEnumerable<ExampleClass> GetAll(string bValue)
{
    foreach (var item in repo.GetAll())
    {
        item.B = bValue;
        yield return item;
    }
}

You can also turn this into an extension method for more fluency:

public static class IEnumerableExtensions
{
    public static IEnumerable<T> Map<T>(this IEnumerable<T> source, Action<T> action)
    {
        foreach (var item in source)
        {
            action(item);
            yield return item;
        }
    }
}

// usage
public IEnumerable<ExampleClass> GetAll(string bValue)
{
     return repo.GetAll().Map(x => x.B = bValue);
}
Xiaoy312
  • 14,292
  • 1
  • 32
  • 44
9

You can try LINQ. According to this link: Update all objects in a collection using LINQ , you can do this:

repo.getAll().Select(c => {c.B = value; return c;}).ToList();

However, according to Jon Skeet, it's better to just use Foreach loop. https://stackoverflow.com/a/7851940/5779825

oopsdazie
  • 716
  • 1
  • 7
  • 22
  • 2
    I agree with Jon Skeet, you should use an for each loop and not LINQ. But I just don't want the for each loop within my business logic to keep the code clean. – C. Molendijk Sep 25 '17 at 18:22
8
 return repo.GetAll().ToList().ForEach(i => i.B = bValue);

This should work. Not tested though.

Ram Pratap
  • 1,079
  • 11
  • 8
1

I think you can use this approach:

return exampleList.Select(i => { i.B = bValue; return i; });
scopchanov
  • 7,966
  • 10
  • 40
  • 68
gmaly
  • 21
  • 3