我正在嘗試合并兩個串列,我以為我有一個解決方案,但是如果有兩個PackItem長度相同的 s,結果就會不符合預期。
期望/要求。
- 對于每個長度,兩個串列包含相同的總件數。
編輯:添加了代碼以闡明輸入要求。
- 可以在多個
PacksItems 中使用相同的長度。 - 可以從多個
CoilNums 中產生相同的長度。
目標是包含一個串列,其中包含每個PackItem.ID/的唯一條目CoilNum。
輸出的要求是每個長度的總件數與輸入串列匹配。
這是我到目前為止的代碼。
public class PackItem
{
public int ID { get; set; }
public int Quantity { get; set; }
public string Length { get; set; }
}
public class ProductionInfo
{
public ProductionInfo AddID(PackItem item)
{
LineID = item.ID;
Quantity = Math.Min(Quantity, item.Quantity);
return this;
}
public int LineID { get; set; }
public string CoilNum { get; set; }
public int Quantity { get; set; }
public string Length { get; set; }
}
private void DoTest()
{
var packItems = new List<PackItem>()
{
new PackItem() {ID = 4, Quantity = 5, Length = "10"},
new PackItem() {ID = 5, Quantity = 2, Length = "4"},
new PackItem() {ID = 6, Quantity = 1, Length = "4"}
};
var productionInfoList = new List<ProductionInfo>()
{
new ProductionInfo() { CoilNum = "A", Quantity = 4, Length = "10"},
new ProductionInfo() { CoilNum = "B", Quantity = 1, Length = "10"},
new ProductionInfo() { CoilNum = "B", Quantity = 2, Length = "4"},
new ProductionInfo() { CoilNum = "A", Quantity = 1, Length = "4"},
};
//assert that both lists meet input requirements
var result1 = "";
var sum1 = packItems.GroupBy(i => i.Length);
foreach (var group in sum1) result1 = $"{group.Sum(i=>i.Quantity)} | {group.Key}\n";
var input2 = "";
var result2 = "";
var sum2 = productionInfoList.GroupBy(i => i.Length);
foreach (var group in sum2) result2 = $"{group.Sum(i => i.Quantity)} | {group.Key}\n";
Console.WriteLine("packItems: \nSum(Quantity) | Length");
Console.WriteLine(result1);
Console.WriteLine("productionInfoList: \nSum(Quantity) | Length");
Console.WriteLine(result2);
if (result1 == result2)
{
Console.WriteLine("Both Lists have the same quantity of each length");
}
else
{
Console.WriteLine("Error: Both Lists do not have the same quantity of each length");
return;
}
var merged = productionInfoList.SelectMany(x => packItems, (x, y) => new { x, y })
.Where(i => i.x.Length == i.y.Length)
.Select(i => i.x.AddID(i.y));
Console.WriteLine("ID | Coil | Qty | Length");
foreach (var item in merged)
{
Console.WriteLine($"{item.LineID} | {item.CoilNum} | {item.Quantity} | {item.Length}");
}
}
//expected output
ID | Coil | Qty | Length
4 | A | 4 | 10
4 | B | 1 | 10
5 | B | 2 | 4
6 | A | 1 | 4
//actual output
ID | Coil | Qty | Length
4 | A | 4 | 10
4 | B | 1 | 10
5 | B | 2 | 4
6 | B | 1 | 4
5 | A | 1 | 4
6 | A | 1 | 4
I'm stuck at this point and they only way I can think of is splitting each of these lists into individual items of one each, and then compiling a list by looping through them one by one.
Is there a way this can be done with Linq?
uj5u.com熱心網友回復:
這是一種產生正確輸出的方法。有沒有更簡單的方法來做到這一點?這只能用 Linq 來完成嗎?
private void DoTest()
{
var packItems = new List<PackItem>()
{
new PackItem() {ID = 4, Quantity = 5, Length = "10"},
new PackItem() {ID = 5, Quantity = 2, Length = "4"},
new PackItem() {ID = 6, Quantity = 1, Length = "4"}
};
var productionInfoList = new List<ProductionInfo>()
{
new ProductionInfo() { CoilNum = "A", Quantity = 4, Length = "10"},
new ProductionInfo() { CoilNum = "B", Quantity = 1, Length = "10"},
new ProductionInfo() { CoilNum = "B", Quantity = 2, Length = "4"},
new ProductionInfo() { CoilNum = "A", Quantity = 1, Length = "4"},
};
//first create a list with one item for each pieces
var individualProduction = new List<ProductionInfo>();
foreach (var item in productionInfoList)
{
for (int i = 0; i < item.Quantity; i )
{
individualProduction.Add(new ProductionInfo()
{
Quantity = 1,
Length = item.Length,
CoilNum = item.CoilNum
});
}
}
//next loop through and assign all the pack line ids
foreach (var item in individualProduction)
{
var packItem = packItems.FirstOrDefault(i => i.Quantity > 0 && i.Length == item.Length);
if (packItem != null)
{
packItem.Quantity -= 1;
item.LineID = packItem.ID;
}
else
{
item.Quantity = 0;
}
}
//now group them back into a merged list
var grouped = individualProduction.GroupBy(i => (i.CoilNum, i.LineID, i.Length));
//output the merged list
var merged1 = grouped.Select(g => new ProductionInfo()
{
LineID = g.Key.LineID,
CoilNum = g.Key.CoilNum,
Length = g.Key.Length,
Quantity = g.Count()
});
}
uj5u.com熱心網友回復:
很不清楚......這個關閉了所需的結果,但沒有考慮任何數量,因此PackItem總是選擇拳頭。如果減少pItem.Quantity這將選擇下一個可用的 pItem.ID,其中數量 > 0。但這將需要更多代碼:)
var results = productionInfoList.Select(pInfo =>
{
var pItem = packItems.First(z => z.Length == pInfo.Length);
return new { pItem.ID, pInfo.CoilNum, pInfo.Quantity, pInfo.Length };
}).ToList();
uj5u.com熱心網友回復:
當您的目標是:The goal is to contain a list the contains a unique entry for each PackItem.ID/CoilNum.您的底部答案是正確的,因為它有一個唯一的 id 線圈編號對。你正在尋找的是一個不同的uniquenes。
var l = packItems.Join(productionInfoList, x => x.Length, y => y.Length, (x, y) => { y.AddID(x); return y; }).GroupBy(x => new { x.CoilNum, x.Length }).Select(x => x.First());
目前尚不清楚案例的確切規則,但在這里我使用 Length 作為唯一鍵來執行連接操作(建議為連接操作使用不同的唯一鍵)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/324904.html
