Search code examples
c#arrayslinq

C# ToArray conversion merged into one line with resulting array element change


I am wondering if it is possible to merge ToArray conversion with resulting array single element change into one statement.

This works perfectly

var response = Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
    Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
    TemperatureC = Random.Shared.Next(-20, 55),
    Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();

response[0].Summary = "Some text";

return response;

However this one, returns only string contained in Summary

return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
    Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
    TemperatureC = Random.Shared.Next(-20, 55),
    Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray()[0].Summary = "Some text";

Solution

  • Well, to have Linq only solution, you can try adding ternary operator:

      Summary = index == 1 
        ? "Some text" 
        : Summaries[Random.Shared.Next(Summaries.Length)]
    

    Code:

    return Enumerable
      .Range(1, 5)
      .Select(index => new WeatherForecast {
        Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
        TemperatureC = Random.Shared.Next(-20, 55),
        Summary = index == 1 
          ? "Some text" // 1st item is special one
          : Summaries[Random.Shared.Next(Summaries.Length)] // business as usual
      })
      .ToArray();
    

    Another (more general) possibility is an extra Select in the very end:

    return Enumerable
      .Range(1, 5)
       ...
       /* A lot of Linq here */
       ...
      .Select((value, index) => index == 0 
         ? "Some text"
         : value)
      .ToArray();