Search code examples
javascriptc#arraysentity-frameworkjsonresult

Convert Javascript Reduce Function to C#


I am trying to convert this function from Javascript to C#. The goal is to receive a List of contracts and sort them into subgroups, bundling them if they have the same client.

> let c1 = {id:1,name:"c1"} 
> let c2 = {id:2,name:"c2"} 
> let c3 =  {id:2,name:"c3"} 
> let c4 = {id:1,name:"c4"} 
> let c5 = {id:3,name:"c5"}
> let list = [c1,c2,c3,c4,c5]
> 
> const groupByKey = (array, property) => {   return
> array.reduce((accumulator, object) => {
>     const key = object[property];
> 
>     if (!accumulator[key]) {
>       accumulator[key] = []
>     }
>     accumulator[key].push(object)
>     return accumulator;   }, {}) }
> 
> groupByKey(list, "id") 
> 
> // input = let list = [c1,c2,c3,c4,c5] //output =
> {"1":[{"id":1,"name":"c1"},{"id":1,"name":"c4"}],"2":[{"id":2,"name":"c2"},{"id":2,"name":"c3"}],"3":[{"id":3,"name":"c5"}]}

// preferebly the output would be a list of Lists containting the contracts bundled.

Update: I have written the function the problem is that i need to return just the contracts ids, not the whole object.

desired output [[c1.id,c4.id],[c2.id,c3.id],[c5.id]]

This is what i currently have.

        public JsonResult checkForSameClient(long[] listOfContracts)
        {
// here i grab the list of contracts ids then go to my repository and find //the whole objects to be compared.






IQueryable<ContratEspace> contrats = contratEspaceRepository.Get(1, listOfContracts.Count(), listOfContracts);
                var contratList = contrats.ToList();

            var finalArray = contrats.GroupBy(c => c.id_clientGestion).ToList();
            return new JsonResult() { Data = finalArray };
        }

But this is not returning the Json.Data correctly im having the error:

SyntaxError: Unexpected token < in JSON at position 0
    at JSON.parse (<anonymous>)
    at fromJson (angular.js:1282)
    at defaultHttpResponseTransform (angular.js:10133)
    at angular.js:10224
    at forEach (angular.js:321)
    at transformData (angular.js:10223)
    at transformResponse (angular.js:10996)
    at processQueue (angular.js:15552)
    at angular.js:15568
    at Scope.$eval (angular.js:16820)

Solution

  • Since GroupBy is built in .NET it is not necessary to write the aggregate function.

    How to group a list in C#:

    var list = new [] {
       new { Id = 1, Name = "c1"},
       new { Id = 2, Name = "c2"},
       new { Id = 2, Name = "c3"},
       new { Id = 1, Name = "c4"},
       new { Id = 3, Name = "c5"},
    };
    
    var grouped = list.GroupBy(x => x.Id);
    

    The lambda function x => x.Id may be tailored to fit your needs

    https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.groupby?view=netcore-3.1