尝试从列表中选择第一个符合条件的索引

时间:2013-12-22 20:42:43

标签: c# list

我有一个List<List<Object>>,其中一个对象具有属性isCurrentlySelected = true。该嵌套列表表示可以以任何配置构造的这些对象的网格(即,网格可以是任何维度,甚至可以是锯齿状的)。

现在,其中一些对象具有属性isSelectable = false,所以我正在尝试创建一个方法,该方法为“方向”获取单个参数,并从当前指定的方向返回第一个符合条件的索引标记为已选中。

到目前为止,我只能使用几个嵌套的for循环和if-else语句来做到这一点,即使这样,它也只适用于一个方向。我想知道是否有更优雅的方法来检查第一个符合条件的元素,最好是使用单一方法。

提前感谢您的帮助,

〜KWiP

编辑:使用代码示例

所以我有Menu类:

public class Menu
    {
        public int x;
        public int y;
        public int width;
        public int height;
        public int lineHeight;
        public float menuTimer = 0.0f;
        public bool menuKeysPressed = false;
        public List<List<Selection>> selections = new List<List<Selection>>();
        public int selectedList = 0;
        public int selectedItem = 0;

其中是子类Selection

public class Selection
        {
            public int x;
            public int y;
            public bool isCurrentlySelected = false;
            public bool isSelectable = true;
            public Color selectedColor = Color.White;
            public Color unselectedColor = Color.Gray;
            public bool isNonText = false;
            public string displayText = "";
            public int textSize;

            public Selection(int xPos, int yPos, string text, int size, bool selectable)
            {
                x = xPos;
                y = yPos;
                displayText = text;
                textSize = size;
                if (!selectable)
                {
                    isCurrentlySelected = false;
                }
            }
        }

Selection对象中的每个MenuMenu.selections中的嵌套列表中以其索引的形式具有X和Y坐标。在每个菜单中,通常只有一个Selection,其isCurrentlySelected属性设置为true。

public Menu(int xPos, int yPos, int wdth, int hght, int lists = 0, int items = 0, bool allSelectable = true)
        {
            x = xPos;
            y = yPos;
            width = wdth;
            height = hght;
            if (items > 0 && lists <= 0)
            {
                lists = 1;
            }
            for (int i = 0; i < lists; i++)
            {
                selections.Add(new List<Selection>());
                for (int j = 0; j < items; j++)
                {
                    selections.ElementAt(i).Add(new Selection(((wdth / items) * j) + xPos, ((hght / lists) * i) + yPos, "", 20, allSelectable));
                }
            }
            if (items > 0)
            {
                selections.ElementAt(0).ElementAt(0).isCurrentlySelected = true;
            }
        }

现在,在Menu类中,我正在尝试创建一个取消选择当前所选索引的方法,然后在特定方向上选择下一个最接近的合格索引,如果在达到了指数范围的终点。不幸的是,我所能想到的只是这个混乱,目前只能在北方工作,并且需要扩大到大小的4倍以适应所有方向。

public void nav(Point currentSelected, int dir) // The 4 cardinal directions are represented by an int: 0 for North and continuing clockwise from there.
        {
            int newRow = currentSelected.Y;
            int newIndex = currentSelected.X;
            switch (dir)
            {
                case 0: // Operations to select next eligible N index.
                    if (this.selections.Count <= 1)
                    {
                        return;
                    }
                    else
                    {
                        int firstOpenRow = this.selections.Count;
                        for (int i = 0; i < this.selections.Count; i++)
                        {
                            int difference = i - currentSelected.Y;
                            if (difference > 0 && difference < firstOpenRow && this.selections.ElementAt(i).ElementAt(currentSelected.X).isSelectable == true)
                            {
                                firstOpenRow = i;
                            }
                        }
                        if (firstOpenRow == this.selections.Count)
                        {
                            for (int i = 0; i < this.selections.Count; i++)
                            {
                                int difference = i - currentSelected.Y;
                                if (difference < 0 && difference < firstOpenRow && this.selections.ElementAt(i).ElementAt(currentSelected.X).isSelectable == true)
                                {
                                    firstOpenRow = i;
                                }
                            }
                            if (firstOpenRow == this.selections.Count)
                            {
                                firstOpenRow = currentSelected.Y;
                            }
                        }
                        this.selections.ElementAt(currentSelected.Y).ElementAt(currentSelected.X).isCurrentlySelected = false;
                        this.selections.ElementAt(firstOpenRow).ElementAt(currentSelected.X).isCurrentlySelected = true;
                    }
                    break;
                case 1:
                    // Add operations for E here
                    break;
                case 2:
                    // Add operations for S here
                    break;
                case 3:
                    // Add operations for W here
                    break;
            }
        }

1 个答案:

答案 0 :(得分:0)

您选择的数据结构并不适合您需要进行的查询。也许您应该考虑投入更多时间来创建链接网格。类似的东西:

class Item
{
    Item North { get; private set; }
    Item South { get; private set; }
    Item West { get; private set; }
    Item East { get; private set; }
}

就像那样,如果你寻找下一个'左'项,你就可以去西方,直到你到达 null 或者遇到一个可选的项目。

否则,区分不同类型的方向是有意义的。仅仅因为你的代码较少并不意味着你的程序运行得更快。根据您为实现目标而必须进行多少操作来考虑您的算法,而不是考虑多长时间。

很抱歉,如果那不是你要找的答案。