i am working on a ticket where there is a array of data i am passing as parameter to a method and based on the parameter and another date parameter i want filtered result but i am not able to get that result
here is my code
public void Test1()
{
// Arrange
var first = new Level
{
Code = "P3",
Date= DateTime.Parse("01 March 2022")
};
var second = new Level
{
Code = "P3",
Date= DateTime.Parse("01 April 2022")
};
var firstbrk = new Level
{
Code = "B1",
Date = DateTime.Parse("01 March 2022")
};
var secondbrk = new Level
{
Code = "B1",
Date= DateTime.Parse("01 April 2022")
};
var data = new[]
{
first ,
second,
firstbrk,
secondbrk
};
// Act
var main = Handler.GetExtras(data, DateTime.Parse("02 April 2022"));
// Assert
CollectionAssert.AreEquivalent(main , new[] { second, secondbrk });
}
[Test]
public void Test2()
{
// Arrange
var first= new Level
{
Code = "A3",
Date= DateTime.Parse("01 March 2022")
};
var second= new Level
{
Code = "A3",
Date= DateTime.Parse("01 April 2022")
};
var firstbrk= new Level
{
Code = "B1",
Date = DateTime.Parse("01 March 2022")
};
var secondbrk = new Level
{
Code = "B1",
Date= DateTime.Parse("01 April 2022")
};
var data= new[]
{
second,
first,
sceondbrk,
firstbrk
};
// Act
var main = Handler.GetExtras(data, DateTime.Parse("02 April 2022"));
// Assert
CollectionAssert.AreEquivalent(main, new[] { second, secondbrk });
}
Here is handler code
public static IEnumerable<Extra> GetExtras(IEnumerable<Extra> main, DateTime idate)
{
return main.GroupBy(x => x.Code).Select(x => x.LastOrDefault(x => x.Date< idate));
}
Here in handler code the issue is only test1 is satisfying test2 is not working because of LastOrDefault used
i want the the input which is supplier to handler method should be first filtered based on Code
so with every code it should get the data and then with that it should check that Date from the class Extra should be less than idate and then only latest date from the group of that particular code should get picked
e.g if date is 2 March 2022 and 2 April 2022 for code T3
and date is 5 march 2022 and 1 April 2022 for code B1 and i date is 5 April
so for code T3 2 April should get picked and for code B1 1 April Should get picked
also if input is sent in incorrect order like Test case Test2 then it should order the input in proper order and then do above stuff
Thanks in advance for help
CodePudding user response:
you have to fix GetExtras method since your class name Level, not Extra And you can not group your data , it will be the same
public static IEnumerable<Level> GetExtras(IEnumerable<Level> main, DateTime idate)
{
return main.Where(x => x.Date < idate).OrderByDescending(x => x.Date).Take(1);
}
if you still want to group you can use this code, but result will be the same
public static IEnumerable<Level> GetExtras(IEnumerable<Level> main, DateTime idate)
{
return main.GroupBy(x => new { x.Code, x.Date }).Where(x => x.Key.Date < idate)
.Select( x=> new Level {Code= x.Key.Code, Date= x.Key.Date}).OrderByDescending(x => x.Date).Take(1);
}
CodePudding user response:
This looks extremely similar to this question, except that here you want the one entry that matches the criteria for each Code
. I am reusing logic from the answer that I gave for the other question here, but using .GroupBy()
to group by Code
:
public static IEnumerable<Extra> FetchExtras(Extra[] lvl, DateTime idate)
{
return lvl
.GroupBy(extra => extra.Code)
.Select(gr => gr.Where(x => x.Date < idate).MaxBy(x => x.Date));
}
.MaxBy()
is available from System.Linq
from .Net 6.