生产单品和移动柜台

本文关键字:柜台 移动 生产单 | 更新日期: 2023-09-27 18:07:21

我正在解决一个问题,我需要一次向消费者提供一个项目,并将柜台向前移动,以便下一个项目,等等,直到项目用完。我想出了代码的初稿(见下文)。底层数据结构包含一个字典,它包含字符串作为键,并保存另一个字典作为值,它保存实体类型的对象。

我有一种感觉,我确实需要以某种方式维护状态,所以我尝试使用yield return语句,但不确定如何将其粘合在一起。此外,我认为使用forearch/iterator可能需要调整,因为消费者将调用GetNextItem(),直到它返回false(意味着耗尽项目)。

private static Dictionary<string, Dictionary <uint,Entity>> dt;   
private uint localCounter=0 , globalCounter = 0;
public Entity GetNextItem()
{
    foreach (string key in dt.Keys )
    {
        if (MoveCounters(key)) //counter is moved, so process the next item
        {
            yield return dt[key][localCounter];
        }
    }
}
private bool MoveCounters(string key)
{
    if (++globalCounter > dt.Count) return false; //hit the limit
    if (++localCounter >  dt[key].Count)
    {
        globalCounter++;
        return true;
    }
    localCounter++;
    return true;
   }
}

public class Entity
{
    Dictionary<string, string> dtValues; //contains values from CSV file.
}

生产单品和移动柜台

当您移动到下一个子列表时,您无法将localCounter重置为零。

也就是说,你可以更容易地做到这一点:

foreach (var subdt in dt.Values)
   foreach (var item in subdt.Values)
       yield return item;

但是使用LINQ SelectMany更容易

return dt.Values.SelectMany(subdt => subdt.Values);

请注意,最后一个没有使用yield return,因为LINQ产生可枚举对象,您只需返回它。

如果您也想记录键和计数器,请尝试这样做:

int iList = 0;
foreach( var subdt in dt ) {
    /* log iList, subdt.Key */
    int iItem = 0;
    foreach( var item in subdt.Value ) {
       /* log iItem, item.Key */
       ++iItem;
       yield return item.Value;
    }
    ++iList;
}