简体   繁体   中英

"Sequence contains no matching element" C#

I'm making an application which has Container 's with X , Y and Z properties. These containers go in a Ship . All the containers are either normal, Cooled or Valuable . The requirements for valuable is that the X -1 and X + 1 are empty. So basically the containers next to the valuable Container must be empty. And when they are empty I want it to return the Container in between.

I pre-made a List<Container> with X , Y and Z .

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
             }
         }
    }
}

Question: I am trying to make the method CheckValuableAndReturnPlace() return an empty container where the coordinates of the other Container 's X - 1 and X + 1 are Empty and not Valuable too.

 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();
}

For clarification: I want an Empty Container (which, all of them in the list already are), where the sides, so X -1 and X +1 are Empty too. Or if the place is X = 1 than only X = 2 needs to be empty and non-valuable or X = MaxXLength than only X = MaxXlength - 1 needs to be empty and non-valuable

The Unit test:

[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));
}

Last EDIT:

Sorry my question was this vague, I tried my hardest not to give excess information that wasn't needed, but I figured it out. Thanks for the one guy for trying to give me an answer :p.

I am assuming there is more to this question than the title. But if the error mentioned in your title is stopping you, please see this stack post. Sequence contains no matching element

If I understand correctly, you want to find the first container where it AND its neighbors are all empty and not valuable. I can't quite grasp why, but that seems to be what your post describes.

You mention wanting to find all the containers where the sides also meet these requirements but then only reference the x direction.

I want an Empty Container(which, all of them in the list already are), where the sides, so X -1 and X +1 are Empty too.

I am following the words("sides") not the logic(only x mentioned) so far since you are asking for advice on the logic.

If i were you, i would rely on a little extra encapsulation to clean up this issue. Separate sorting the boxes and tracking their position. One way you could do this looks kind of like this.

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;
    }
}

There are a lot of ways to encapsulate higher dimensional arrays. and i cannot discern from the context of your question what would be best.

If you intend to model this like a ship yard where the boxes are (theoretically) in a grid pattern and you want to check the neighbors that way, then a three dimensional list is probably the way to go.

if you want a flat grid with each vertical stack of containers as its own list, you can do that too, its all arbitrary and only matters based on what you want to use it for.

but as it stands you can check the emptiness and lack there of as simply as

public ContainerGrid ShipYard;
public Container FindFirstEmptyContainer(){
    return ShipYard.OrderedList.FirstOrDefault(x=>ShipYard.IsEmptyAndNeighborsEmpty(x.x,x.y,x.z));
}

ordering the list as you please, but still maintaining the same spacial relationships.

Does that answer what you are asking about? Could you clarify anything that is not being covered by this answer?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM