user2643287
user2643287

Reputation: 131

How to remove from an List Object in c#

I have an Action method in my controller which returns a List Object

  Public ActionResult GetCats(long Id,string strsortorder,string dltIds)
  {
      var Result=objrepo.GetCats(Id);//this method returns me List of Result

  }

My array looks like this:

 var Result=[{CatId:1015,CatName:Abc},{CatId:1016,CatName:Acd},  
{CatId:1017,CatName:Adf},{CatId:1018,CatName:CDdf},{CatId:1019,CatName:asdas},  
{CatId:1020,CatName:Abc},{CatId:1021,CatName:Abc},{CatId:1022,CatName:Abc},  
{CatId:1023,CatName:Abc},{CatId:1024,CatName:Abc}]

What I want to do is:
Using two more parameters in my Action Method "strsortorder" and "dltIds" that have a list of ids like this:

    strsortorder="1021,1015,1016,1019,1022";
    dltIds="1017,1018,1020";

From this the "Result" returned from my method , I want to remove the records which are in "dltids" and the remaining array should be sorted in the order which I have in "strsortorder";

In the end the new object should look like this:

var NewResult=[{CatId:1021,CatName:Abc},{CatId:1015,CatName:Abc},  
{CatId:1016,CatName:Acd},{CatId:1019,CatName:asdas},{CatId:1022,CatName:Abc},  
{CatId:1023,CatName:Abc},{CatId:1024,CatName:Abc}]

Can any one help me in acheiving this in linq or any other way?
I want to avoid any type of loop or froeach here for max extent, I know it can be done by looping but I want to avoid this since the result can sometimes contain large amounts of data.

Upvotes: 1

Views: 102

Answers (1)

Hogan
Hogan

Reputation: 70523

I realized you can use an ArrayList instead of a Dictionary and it would be faster. I think Dictionary is clear how it works but here is the "better" implementation using array list:

 var excludeList = dltIds.Split(",".ToCharArray());
 ArrayList sortList = new ArrayList(strsortorder.Split(",".ToCharArray()));

 var NewResult = 
       Result.Where(item => ! excludeList.Contains(item.CatId.ToString()))
         .OrderBy(item => {
            if (sortList.Contains(item.CatId.ToString()))
              return sortList.IndexOf(item.CatId.ToString());

            return sortList.Count;
         });

Original answer below:

Public ActionResult GetCats(long Id,string strsortorder,string dltIds)
{
  var Result=objrepo.GetCats(Id);//this method returns me List of Result

  var excludeList = dltIds.Split(",".ToCharArray());
  int orderCount = 0; // used in the closure creating the Dictionary below
  var sortList = strsortorder.Split(",".ToCharArray())
                             .ToDictionary(x => x,x => orderCount++);

  // filter
  var NewResult = 
        Result.Where(item => ! excludeList.Contains(item.CatId.ToString()))
              .OrderBy(item => {
                 if (sortList.ContainsKey(item.CatId.ToString()))
                   return sortList[item.CatId.ToString()];
                 return sortList.Count();
              });
}

How this works:

First I create lists out of your comma separated exclude list using split.

This I create a dictionary with the key being the ordering ID and the value being an integer that goes up by one.

For the filtering I look to see if an item is in the exclude array before I continue processing the item.

I then do a sort on matching against the key and the dictionary and returning the value -- this will sort things in the order of the list since I incremented a counter when creating the values. If an item is not in the dictionary I return one more than the maximum value in the dictionary which must be the count of the items. (I could have used the current value of orderCount instead.)

Questions?

Upvotes: 1

Related Questions