首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何实现多项选择?

如何实现多项选择?
EN

Stack Overflow用户
提问于 2015-02-04 16:27:25
回答 1查看 197关注 0票数 2

我正在开发一个绘图应用程序,用户可以在该应用程序中创建和删除形状,并使用鼠标选择它们来拖动它们。所选形状应在“选择”数组中引用,还是每个形状都应具有isSelected属性?一种方法比另一种方法有什么好处吗?到目前为止,我注意到了这一点(我会用人们发现的任何东西来更新它)。我主要关心的是编程的简单性和性能。这个问题在很大程度上是独立于语言的,但应用程序是用javascript编写的,呈现是在html5画布上完成的。

检查选择状态

虽然我们立即知道如果一个项是通过布尔属性选择的,但是基于数组的解决方案需要遍历数组来搜索该项的引用。这种验证是非常常见的,因为当鼠标悬停选定的形状时,光标应该改变为“拖动”图标,或者当鼠标悬停在非选定的项目上时,会变成“指向手”图标。

取消选择项

使用布尔属性,选择和取消选择特定项是瞬时的。然而,对于数组选择,我们必须首先遍历所选内容,以便在添加或从所选内容中删除项目之前查看该项是否存在。这使得“切换选择”和“添加到选择”选项要慢得多。然而,在这样的绘图程序中,最常见的操作是在选择特定元素之前清除所选内容。使用数组方法,清除所选内容就像替换数组一样简单,而布尔方法要求在所有项上将isSelected属性设置为false。

删除项目

值得一提的是,在删除某项之前,必须将其从选择数组中删除。这个细节在isSelected方法中没有显示出来。

调用所有选定项

应用于所有选定项的操作需要最少的数组代码,因为我们只需遍历所选内容并对每个元素调用该方法。如果选择相对于项目的总数量来说很小,那么只需要通过选择来循环就可以获得相当长的时间增益。对于布尔属性,对所有选定项调用操作所需的时间取决于项目的总数,而不是选择的大小。

绘图时间

选定的项目通常有颜色的边框,可以通过其他元素看到。这意味着必须在所有其他元素前面绘制选择边界。给定项目"n“的数目和选定项目的数目(”s“).

数组解决方案从O(n)2*O(n)呈现。

布尔解决方案需要使用2*O(n)来呈现。

虽然您可能认为这说明选择数组方法本身是合理的,但请记住,重绘只在操作被触发之后才完成,而不是每秒60次。检查尖头形状,以确定它是否被选中比绘图更常见。唯一可能明显慢下来的功能是拖动、拉伸和矩形选择。由于应用程序用于表示现实生活中的项目,人们通常在键盘上输入他们想要的大小,而不是实际拖动项目。

Encapsulation

封装使用布尔属性更强,因为条目知道它们是否被选中,而无需查看应用程序范围变量。这种差异在严格的范围内可能有很大的意义,但在javascript中并不是什么大问题。我想人们可能会认为,选择自己不是形状的角色。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-06 20:53:46

我已经实现了布尔isSelected属性,并且随着应用程序的增长,我构建了越来越多的应用于所有元素的函数。在每个函数中,我必须放置一个for循环,以确保只更改选定的项。我将编写一些伪代码来保持这个解决方案语言的不可知论。

代码语言:javascript
运行
复制
for each item {
  if item is selected
    do stuff
}

到处都有同样的循环让我很恼火,我觉得这是错误的。当您在函数之间复制粘贴代码部分时,这绝不是一个好迹象。因此,我创建了一个getSelection()函数,它返回所选元素的数组。这似乎解决了我以前的问题,通过提取可怕的循环。

代码语言:javascript
运行
复制
function getSelection() {
  selection = new empty array

  for each item in selection {
    if item is selected
      add item to selection array
  }
  return selection
}

function doStuffOnSelection() {
  selection = getSelection()

  for each item in selection {
    do stuff
  }
}

但这只暴露了更糟糕的事情。操作数组(不断地将项推入数组、创建数组等)比仅仅查看它们要慢得多。这一变化大大减缓了应用程序的速度,以至于在Firefox中,我甚至不能一次拥有100条条目,而我过去可以拥有2000条而不需要一个框架下降。这一切都是因为我现在创建了一个数组。这是因为需要在程序的每个帧上调用getSelection函数,以便在所有选定的元素上绘制蓝色边框!

当我发布这个问题时,我不确定这是否是过早的优化,现在我知道它不是。

使用数组跟踪选定项的主要缺点

  • 您需要查看所有选定的元素,以确定是否选择了特定元素并更改该状态。
  • 要从所有元素的数组中删除选定的元素,需要对数组进行研究,这在任何一个数组都很大的情况下尤为缓慢。

使用每项布尔值跟踪选定项的主要缺点。

  • 您需要查看所有元素,以了解选择了哪些元素并更改该状态。

所以我已经决定了一个更好的方法来处理所有的消极方面:两者都做。我将在后台保留一个所选项目的数组,当选择和取消选择时,它将被更新。这样就消除了仅数组选择的所有坏方面,因为我不再需要搜索任何数组来确定是否选择了特定元素(我可以查看它的布尔值)。适用于选定项但不选择和取消选择项(例如移动、调整大小、绘制)的所有函数都可以通过选择数组循环。两个世界中最好的!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28326399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档