数据过滤算法

时间:2009-04-15 21:09:42

标签: javascript algorithm filter mootools

您能否建议我过滤数据的算法。

我正在使用javascript并试图写出一个过滤数据数组的过滤函数。我有一个数据数组和一个过滤器数组,所以为了对每个数据应用每个过滤器,我写了2循环

foreach(data)
{
  foreach(filter)
  {
   check data with filter
  }
}

这不是正确的代码,但简而言之,我的功能所做的,问题是需要花费大量时间,有人可以提出更好的方法。

我正在使用Mootools库,数据数组是JSON数组

数据和过滤器的详细信息

数据是让用户说的JSON数组,所以它将是

data = [{"name" : "first", "email" :  "first@first", "age" : "20"}.
        {"name" : "second", "email" :  "second@second", "age" : "21"}
        {"name" : "third", "email" :  "third@third", "age" : "22"}]

过滤器数组基本上是针对不同数据字段的自定义类

alFilter[0] = filterName;
alFilter[1] = filterEmail;
alFilter[2] = filterAge;

因此,当我进入第一个for循环时,在上面的例子中我获得了一个JSON opbject(第一行)。 当我进入第二个for循环(过滤器循环)时,我有一个过滤器类,它提取当前过滤器工作的确切字段,并使用相应的数据字段检查过滤器。

所以在我的例子中

foreach(data)
{
 foreach(filter)
{
  //loop one - filter name
 // loop two - filter email
 // loop three - filter age
}
}

当第二个循环结束时,我设置一个标志,表示数据是否已被过滤,并根据它显示数据。

5 个答案:

答案 0 :(得分:3)

您将不得不向我们提供有关数据和过滤器的确切结构的更多详细信息,以便真正帮助您。过滤器是用于选择数据子集还是用于修改数据?过滤器在做什么?

那就是说,有一些一般的建议:

  1. 减少工作量。有什么方法可以限制你正在处理的数据量吗?一些预过滤器可以在你进行主循环之前快速运行并减少它吗?
  2. 尽快打破内循环。如果其中一个过滤器拒绝了一个数据,则跳出内部循环并继续前进到下一个数据。如果可以,那么您还应该尝试将最具选择性的过滤器放在首位。 (这假设您的过滤器用于拒绝列表中的项目,而不是修改它们)
  3. 在过滤器执行的计算中检查冗余。如果它们中的每一个执行一些共享某些子例程的复杂计算,那么可能会使用memoizationdynamic programming来避免冗余计算。
  4. 真的,这一切都归结为代码的所有三个级别的第一点,做更少的工作。你可以通过限制外循环中的项目来减少工作量吗?通过在特定过滤器之后停止并首先执行最具选择性的过滤器来减少工作量?通过不在每个过滤器内部进行任何冗余计算来减少工作量?

答案 1 :(得分:2)

这就是你应该怎么做的。诀窍是优化“使用过滤器检查数据”-part。您需要遍历所有数据并检查所有过滤器 - 您将不会比这更快。

避免字符串比较,尽可能使用数据模型,尝试使用filter减少每次传递的数据集等。

如果没有进一步的了解,很难为您优化这一点。

答案 2 :(得分:2)

您应该对过滤器的应用程序进行排序,以便优化两件事:昂贵的检查应该是最后的,并且应该首先检查消除大量数据的检查。然后,一旦出现“结果”结果,你应确保检查被缩短。

答案 3 :(得分:1)

如果您的过滤器正在查找特定值,范围或文本的开头,则jOrder(http://github.com/danstocker/jorder)将适合您的问题。

您需要做的就是创建一个像这样的jOrder表:

var table = jOrder(data)
    .index('name', ['name'], { grouped: true, ordered: true })
    .index('email', ['email'])
    .index('age', ['age'], { grouped: true, ordered: true, type: jOrder.number });

然后调用table.where()来过滤表格。

当您正在寻找完全匹配时:

filtered = table.where([{name: 'first'}, {name: 'second'}]);

当您在寻找某个范围的某个字段时:

filtered = table.where([{age: {lower: 20, upper: 21}}], {mode: jOrder.range});

或者,当您要查找以给定字符串开头的值时:

filtered = table.where([{name: 'fir'}], {mode: jOrder.startof});

与嵌套循环相比,过滤速度会更快。

答案 4 :(得分:0)

假设过滤器删除了数据,如果它不匹配,我建议你切换两个循环,如下所示:

foreach(filter) {
    foreach(data) {
        check data with filter
    }
}

通过这样做,第二个过滤器不必处理所有数据,而只需处理通过第一个过滤器的数据,依此类推。当然,上面的提示(比如最后进行昂贵的检查)仍然是正确的,还应该加以考虑。