【问题标题】:"Sequence contains no matching element" C#“序列不包含匹配元素”C#
【发布时间】:2019-12-10 09:32:22
【问题描述】:

我正在制作一个具有ContainerXYZ 属性的应用程序。这些容器进入Ship。所有容器都正常,CooledValuable。有价值的要求是 X -1 和 X + 1 是空的。所以基本上贵重容器旁边的容器必须是空的。当它们为空时,我希望它在两者之间返回Container

我用XYZ 预先制作了一个List<Container>

public void ConstructShip()
{
    for (int x = 1; x < widthX + 1; x++)
    {
        for (int y = 1; y < lengthY + 1; y++)
        {
             for (int z = 1; z < heightZ + 1; z++)
             {
                 SortedContainers.Add(new Container(x, y, z, true, false, false, 0)); //xyz, (bool)empty, (bool)valuable, (bool)cooled, weight
             }
         }
    }
}

问题:我试图让方法CheckValuableAndReturnPlace() 返回一个空容器,其中另一个ContainerX - 1X + 1 的坐标是Empty 而不是Valuable

 private Container CheckValuableAndReturnPlace()
 {
    Container freeContainer = SortedContainers
    .First(c => c.X > 0 && c.X <= WidthX && c.Empty && c.Z <= HeightZ &&
    SortedContainers.First(c2 => c2.X == c.X - 1).Empty &&
    SortedContainers.First(c2 => c2.X == c.X + 1).Empty &&
    !SortedContainers.First(c2 => c2.X == c.X - 1).Valuable &&
    !SortedContainers.First(c2 => c2.X == c.X + 1).Valuable)
    .FirstOrDefault();

    if (freeContainer != null)
    {
       return freeContainer;
    }

    return new Container();
}

为了澄清:我想要一个EmptyContainer(列表中的所有这些都已经是),其中边,所以 X -1 和 X +1 也是Empty。或者,如果位置是 X = 1,则只有 X = 2 需要为空且无价值或 X = MaxXLength 而不是只有 X = MaxXlength - 1 需要为空且无价值

单元测试:

[TestInitialize()]
public void Initialize()
{
    Ship ship = new Ship(4, 3, 3); //lengthX, widthY, heightZ

    for (int x = 1; x < 5; x++)
    {
        for (int y = 1; y < 4; y++)
        {
            for (int z = 1; z < 4; z++)
            {
                ship.SortedContainers.Add(new Container(x, y, z, true, false, false, 0));
            }
        }
    }
}

[TestMethod()]
public void CheckValuableAndReturnPlaceTest_Working()
{
    Container freeContainer = ship.CheckValuableAndReturnPlace();
    Container expectedContainer = new Container(1, 1, 1, true, false, false, 0);

    Assert.AreEqual(JsonConvert.SerializeObject(expectedContainer), JsonConvert.SerializeObject(freeContainer));
}

最后编辑:

抱歉,我的问题含糊不清,我尽力不提供不必要的过多信息,但我想通了。感谢一位试图给我答案的人:p。

【问题讨论】:

  • SortedContainerStacks.Where((c, i) =&gt; c.X &gt; 0 &amp;&amp; c.X &lt; SortedContainerStacks.Count - 1 &amp;&amp; SortedContainerStacks[c.X - 1].Empty &amp;&amp; SortedContainerStacks[c.X + 1].Empty).FirstOrDefault()?
  • GSerg 的建议实际上似乎相当不错,并且看起来它可以处理边缘情况,但它总是会说第一个和最后一个容器有价值。如果您希望它们唯一的邻居是否为空,您可能希望在您的规范中澄清它们是否有价值。此外,您可以使用Any,而不是使用FirstOrDefault 然后检查它是否是null
  • 我不清楚这个问题 - 你指的是标题中的错误,然后你谈论“返回”一个容器但提出了一个 void 方法,然后描述一个失败的测试但不显示测试。我认为花更多的精力来澄清这个问题比增加赏金更有帮助。
  • 恐怕还有太多我们不知道的地方。什么是过滤容器?所有这些容器构造函数参数是什么?哪个 LINQ 调用失败?目前我们有部分代码转储,但没有太多迹象表明您为诊断问题所做的工作。

标签: c# algorithm linq


【解决方案1】:

我假设这个问题比标题更多。但是,如果您的标题中提到的错误阻止了您,请参阅此堆栈帖子。 Sequence contains no matching element

如果我理解正确,您想找到第一个容器,它及其邻居都是空的且没有价值。我不太明白为什么,但这似乎是你的帖子所描述的。

您提到想要找到所有侧面也满足这些要求但仅参考 x 方向的容器。

我想要一个空容器(列表中的所有容器都已经存在),其中边,所以 X -1 和 X +1 也是空的。

到目前为止,我关注的是单词(“sides”)而不是逻辑(仅提及 x),因为您正在寻求有关逻辑的建议。

如果我是你,我会依靠一些额外的封装来解决这个问题。单独对盒子进行分类并跟踪它们的位置。你可以这样做的一种方法看起来像这样。

public class ContainerGrid{
    public List<List<List<Container>>> Locations = new List<List<List<Container>>>();

    public List<Container> OrderedList;//you can keep sorting the containers and their current locations separate but still cleanly managed this way.

    public bool IsEmpty(int x, int y, int z){
        //interpreting what you said about needing to be empty and not valuable to be viable. 
        return containers[x][y][z].empty && !containers[x][y][z].valuable;
    }

    public bool IsEmptyAndNeighborsEmpty(int x, int y, int z){
        //i am unsure if you intended sides to be only in the x direction 
        //or if that was just a part of how you explained it in the question
        return IsEmpty(x,y,z) 
          && IsEmpty(x-1,y,z) && IsEmpty(x+1,y,z);
        //&& IsEmpty(x,y-1,z) && IsEmpty(x,y+1,z);
        //&& IsEmpty(x,y,z-1) && IsEmpty(x,y,z+1);
    }
    public bool HasLocation(int x, int y, int z){
        return Locations[x]!=null && Locations[x][y] != null && Locations[x][y][z]!=null;
    }
    public bool Add(Container container){
        if(!HasLocation(container.x,container.y,container.z)){
            if(Locations[container.x]==null)
                AddAt<List<List<Container>>>(Locations, container.x, new List<List<Container>>(), false);
            if(Locations[container.x][container.y]==null)
                AddAt<List<Container>>(Locations[container.x], container.y, new List<Container>(), false);
            if(Locations[container.x][container.y][container.z]==null)
                AddAt<Container>(Locations[container.x][container.y], container.z, container, true);
            OrderedList.Add(container);
        }else return false;
    }

    public bool AddAt<T>(List<T> list, int index, T value, bool nullUntil){
        while(list.Count<=index+1) list.add(nullUntil ? null : value);
        list[index]=value;
    }
}

有很多方法可以封装高维数组。我无法从你的问题的上下文中辨别出什么是最好的。

如果您打算将其建模为像造船厂一样,其中(理论上)盒子呈网格模式,并且您想以这种方式检查邻居,那么三维列表可能是要走的路。

如果您想要一个将每个垂直的容器堆栈作为自己的列表的平面网格,您也可以这样做,这完全是任意的,并且仅取决于您想要使用它的目的。

但就目前而言,您可以像

一样简单地检查空虚和缺乏
public ContainerGrid ShipYard;
public Container FindFirstEmptyContainer(){
    return ShipYard.OrderedList.FirstOrDefault(x=>ShipYard.IsEmptyAndNeighborsEmpty(x.x,x.y,x.z));
}

按您的意愿排序列表,但仍保持相同的空间关系。

这是否回答了您的问题?您能否澄清此答案未涵盖的任何内容?

【讨论】:

  • 我解决了,但既然大家都说我的问题不够清楚。我认为我不应该得到其他人的深思熟虑的答案,但是由于您是唯一一个为我提供了深思熟虑的答案的人,所以我将给您积分。我将删除该帖子,因为我已经想出了我想要的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-23
  • 2013-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
  • 2014-11-09
相关资源
最近更新 更多