Reputation: 77
I have two lists:
static List<Parts> partList = new List<Parts>();
The class it refers to:
class Parts
{
int chassisNumber;
public int ChassisNumber
{
get { return chassisNumber; }
set { chassisNumber = value; }
}
int partsCount;
public int PartsCount
{
get { return partsCount; }
set { partsCount = value; }
}
And the another one:
static List<int> shuffledChassisList = new List<int>();
shuffledChassisList contains a subset of chassis numbers loaded into List ChassisNumber. I want to use shuffledChassisList to query the List into a new List, for ex: List filteredPartList.
I tried to use Linq but failed to write a working solution that would create a new list with filtered results.
Then, I want to use this filtered list to categorise parts into new lists depending on part number count (for ex: I want to copy all parts from List filteredPartList into List emptyPackageList where a Part's partsCount is 0).
So far I got this, but not sure what to write in the foreach loop:
static List<Parts> emptyPackageList = new List<Parts>();
var emptyPackage = filteredPartList.Where(p => p.partsCount == 0);
foreach (var part in emptyPackage)
{
emptyPackageList.Add(new Parts(??));
}
If it is possible to write one method that does this two thing one it is fine for me.
edit:
The reason why I need to have two lists is because I query a database to get the chassis numbers and the parts count which belonging to it. I asked the community, but unfortunately it seems that it is not possible to make this query to run on selected chassis numbers. So I have the partscount for all the chassisnumbers (List<Parts> partList
), which I need to filter with ones I am looking for (List<int> shuffledChassisList
), then group by into new lists by partscount.
If it is possible or easier to filter the List<Parts> partList
by the List<int> shuffledChassisList
then group by the results by partsCount and then copy the Parts into several new lists, then it is also an acceptable solution.
Upvotes: 1
Views: 94
Reputation: 37299
Your class does not specify a constructor and thus has only the default constructor. To populate the new instance with data use the object initializer syntax:
var emptyPackage = filteredPartList.Where(p => p.partsCount == 0);
foreach (var part in emptyPackage)
{
emptyPackageList.Add(new Parts { ChassisNumber = part.ChassisNumber, PartsCount = part.PartsCount } );
}
Also if already using linq then use .Select
to project the new instances:
var emptyPackage = filteredPartList.Where(p => p.partsCount == 0)
.Select(p => new Parts {
ChassisNumber = part.ChassisNumber,
PartsCount = part.PartsCount
}).ToList();
Notice that this creates a deep-copy of your objects as you instantiate a new object and set its properties. If a shallow copy is enough then just:
var emptyPackage = filteredPartList.Where(p => p.partsCount == 0).ToList();
In addition consider the following:
As your properties' implementations are the default ones, use auto-properties:
class Parts
{
public int ChassisNumber { get; set; }
public int PartsCount { get; set; }
}
Implement a copy constructor or the IClonable
interface and then:
//copy constructor
filteredPartList.Where(p => p.partsCount == 0).Select(p => new Parts(p));
//clone
filteredPartList.Where(p => p.partsCount == 0).Select(p => p.Clone());
If I understood your update correctly then:
var result = filteredPartList.Where(p => p.partsCount == 0 &&
shuffledChassisList.Contains(p.ChassisNumber))
.GroupBy(p => partsCount)
.ToList();
Also consider changing shuffledChassisList
to be a HashSet<int>
so Contains
will be an O(1)
operation instead of O(n)
.
Upvotes: 2
Reputation: 2357
Maybe I did not get your proper intention but here is what you can do:
If you have a list of parts and want to categorize them by PartsCount:
var categorized = myList.GroupBy(p=>p.PartsCount, p=>p);
If you want to get all items from one list if id belonging to another:
var filtered = myList.Where(p=>idList.Contains(p.Id));
Maybe by combining both methods you can get what you want (which is still a bit unclear to me)
Upvotes: 1