Object 用于筛选符合条件的对象的最佳数据结构

Object 用于筛选符合条件的对象的最佳数据结构,object,search,data-structures,graph,tree,Object,Search,Data Structures,Graph,Tree,我会尽量概括地提出这个问题,任何语言的回答都可以 假设有几个不同大小的集合,每个集合包含与类别相关的任意值: var colors = ["red", "yellow", "blue"] // 3 items var letters = ["A", "B", "C", ... ] // 26 items var digits = [0, 1, 2, 3, 4, ... ] // 10 items ... // each set has fixed amount of items 我已经拥有的此

我会尽量概括地提出这个问题,任何语言的回答都可以

假设有几个不同大小的集合,每个集合包含与类别相关的任意值:

var colors = ["red", "yellow", "blue"] // 3 items
var letters = ["A", "B", "C", ... ] // 26 items
var digits = [0, 1, 2, 3, 4, ... ] // 10 items
... // each set has fixed amount of items
我已经拥有的此主列表中的每个对象(我希望以某种方式重新构造以优化搜索)都具有这些集合中的一个选择的属性,例如:

var masterList = [
  { id: 1, color: "red", letter: "F", digit: 5, ... },
  { id: 2, color: "blue", letter: "Q", digit: 0, ... },
  { id: 3, color: "red", letter: "Z", digit: 3, ... },
  ...
]
搜索的目的是从主列表中创建可接受对象的新列表。该程序将根据给定的搜索条件过滤主列表,对于每个属性,该搜索条件包含可接受值的列表

var criteria = {
  color: ["red", "yellow"],
  letter: ["A", "F", "P"],
  digit: [1, 3, 5],
  ...
};
我认为某种树是最合适的。我的理解是,它需要平衡,因此根节点将是“中间”对象。我假设每个级别都由一个属性定义,这样当程序从根开始搜索时,它只会沿着符合搜索条件的分支继续搜索,每次删除不符合该级别特定属性的对象

但是,据我所知,此主列表中的许多对象将具有匹配的属性值。这以图形方式将它们连接起来,可能有助于快速搜索

我目前的搜索算法相当直观,只需使用主列表即可完成。节目

  • 遍历搜索条件中的属性
  • 使用每个属性在主列表上迭代,消除许多没有匹配属性的对象,以及
  • 最终删除所有不符合条件的对象。当然,有一些更快的过滤系统,涉及到一个更有组织的数据结构

  • 我能从这里走到哪里?我对本地数据库开放,而不是我认为的另一个数据结构——GraphQL看起来很有趣。这是我的第一个堆栈溢出问题,因此我对任何不礼貌的行为表示歉意,因为我不知道集合的数量,也不知道每个集合中元素的数量。我会建议你做一些非常小的改变,这至少会让事情变得相对快速

    为了保持数学性,我将在这里定义几个术语:

    • 套数-
      n
    • 主列表的大小-
      k
    • 搜索条件中每个属性的大小-
      p
    因此,根据我相信您正在使用的算法,您正在对搜索条件进行
    n
    迭代,因为搜索条件中可能存在
    n
    可能的关键字

    然后在每个
    n
    迭代中,您都在该特定集合的允许值上进行
    p
    迭代。最后,在每个
    np
    迭代中,您都在主列表上迭代
    k
    迭代,并检查是否应该允许记录的这个值

    因此,在一般情况下,您是在
    O(npk)
    时间复杂度下执行此操作的

    所以,我不建议在这里做太多改变

    最好将搜索条件中的值更改为
    (hashset),而不是将其保留为列表,然后在主列表上迭代。遵循以下Python代码:

    def is_possible(criteria, master_list_entry): 
        for key, value in master_list_entry.items(): # O(n)
            if not key in criteria or value not in criteria[key]: # O(1) average
                return False
        return True
    
    def search(master_list, criteria):
        ans = []
        for each_entry in master_list: # O(k)
            if is_possible(criteria, each_entry): # O(n), check above
                ans.append(each_entry)
        return ans
    
    只需调用搜索函数,它将返回过滤后的主列表

    关于更改,请将搜索条件更改为:

    criteria = {
      color: {"red", "yellow"}, # This is a set, instead of a list
      letter: {"A", "F", "P"},
      digit: {1, 3, 5},
      ...
    }
    

    正如您所看到的,我已经提到了每一行的复杂性,因此我们将问题简化为一般情况下的
    O(nk)

    因为我没有集合数量的上下文,也没有集合中元素的数量。我会建议你做一些非常小的改变,这至少会让事情变得相对快速

    为了保持数学性,我将在这里定义几个术语:

    • 套数-
      n
    • 主列表的大小-
      k
    • 搜索条件中每个属性的大小-
      p
    因此,根据我相信您正在使用的算法,您正在对搜索条件进行
    n
    迭代,因为搜索条件中可能存在
    n
    可能的关键字

    然后在每个
    n
    迭代中,您都在该特定集合的允许值上进行
    p
    迭代。最后,在每个
    np
    迭代中,您都在主列表上迭代
    k
    迭代,并检查是否应该允许记录的这个值

    因此,在一般情况下,您是在
    O(npk)
    时间复杂度下执行此操作的

    所以,我不建议在这里做太多改变

    最好将搜索条件中的值更改为
    (hashset),而不是将其保留为列表,然后在主列表上迭代。遵循以下Python代码:

    def is_possible(criteria, master_list_entry): 
        for key, value in master_list_entry.items(): # O(n)
            if not key in criteria or value not in criteria[key]: # O(1) average
                return False
        return True
    
    def search(master_list, criteria):
        ans = []
        for each_entry in master_list: # O(k)
            if is_possible(criteria, each_entry): # O(n), check above
                ans.append(each_entry)
        return ans
    
    只需调用搜索函数,它将返回过滤后的主列表

    关于更改,请将搜索条件更改为:

    criteria = {
      color: {"red", "yellow"}, # This is a set, instead of a list
      letter: {"A", "F", "P"},
      digit: {1, 3, 5},
      ...
    }
    

    正如您所看到的,我已经提到了每一行的复杂性,因此我们将问题简化为一般情况下的
    O(nk)

    这里有更新吗?这里有更新吗?谢谢您的回复!这当然更有效率。如果这是优化的范围,我想我将不得不接受O(nk)。然而,我感到惊讶的是,在执行搜索之前,在主列表的组织方面没有更多的工作可以做。我愿意花大量时间重新构建原始主列表,如果这意味着更快的平均搜索时间。。。即使它仍然是O(nk)感谢您的回复!这当然更有效率。如果这是优化的范围,我想我将不得不接受O(nk)。然而,我感到惊讶的是,在befo之前,在主列表的组织方面没有更多的工作可以做