【问题标题】:Javascript : more clever way to filter thousands of row against thousands of valuesJavascript:更聪明的方法来过滤数千行与数千个值
【发布时间】:2018-11-08 01:03:47
【问题描述】:

我有 2 列的行:产品 SKU 和类别 ID 我只需要返回与 cat_ids 列表匹配的产品 SKU 及其 cat_ids 在 SQL 中是:

SELECT SKU,cat_id FROM myTable where cat_id IN(my_huge cat_ids_list)

但我需要在 Javascript 中从选项卡选项卡返回数据中执行此操作。

显然,我可以使用两个嵌套循环来完成,但这会导致数百万次比较,而且速度太慢

如果我有 30000 个 SKU,则要匹配 1000 个 cat_id,最坏的情况是 30M 测试。

那么有没有一种更聪明的算法方法可以更全局地过滤这个,而不需要太多的测试?

非常感谢

【问题讨论】:

  • 也许尝试递归方法?

标签: javascript algorithm performance


【解决方案1】:

为您的 cat_id 列表使用哈希集,它可以为您提供恒定时间的包含检查。不太熟悉 javascript,但我相信 Set 类型应该可以解决问题。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set

【讨论】:

    【解决方案2】:

    您不需要嵌套循环。使用Set,即恒定时间查找。您需要从类别数组中创建集合,然后使用set.has() 进行过滤:

    let rows = [
        {sku: 1, cat_id:100},
        {sku: 11, cat_id:10},
        {sku: 12, cat_id:10},
        {sku: 13, cat_id:20},
        {sku: 14, cat_id:10},
        {sku: 15, cat_id:20},
        {sku: 16, cat_id:100}
    ]
    //original array of ids to match
    let matchCats = [10, 20]
    
    // make a set from it
    let matchSet = new Set(matchCats)
    
    // filter with has()
    let filtered = rows.filter(item => matchSet.has(item.cat_id))
    console.log(filtered)

    这应该可以让您进行线性时间过滤。

    根据评论修改
    如果你不能使用 ES6,你仍然可以利用常规 javascript 对象可以像哈希一样使用常量键查找这一事实。它不是那么漂亮,但这应该仍然可以在线性时间内工作:

    let rows = [
        {sku: 1, cat_id:100},
        {sku: 11, cat_id:10},
        {sku: 12, cat_id:10},
        {sku: 13, cat_id:20},
        {sku: 14, cat_id:10},
        {sku: 15, cat_id:20},
        {sku: 16, cat_id:100}
    ]
    
    let matchCats = [10, 20]
    
    // make an object of key/null-value pairs
    let matchObj = matchCats.reduce((obj, item) => (obj[item] = null, obj), {})
    let filtered = rows.filter(item => item.cat_id in matchObj)
    console.log(filtered)

    【讨论】:

    • 非常感谢,看起来很酷,但显然,它似乎不适用于我需要使用的 Duktape ECMA 5.1 javascript 引擎
    • @glitchtracker 你是对的 Set 来自 ECMAScript 2015。查看this post 有人想要 ECMAScript 5 的 set 命令。
    • @glitchtracker 你可以使用像哈希映射这样的javascript对象。它不像集合那么干净,因为您本质上是像集合一样使用键,但如果您坚持使用 es5,它是一个不错的选择。例如,请参阅编辑。
    • 嗨,马克,你有使用“像哈希映射这样的 javascript 对象”的示例代码吗?我是个非常新手。另外,我尝试了 Mac OS X JSC 命令行,也没有运行,而 JSC 应该支持 ECMAScript 2015
    • 嗨@glitchtracker,我发布的编辑显示了这一点。它使用这个 cat_ids 列表中的键创建一个对象,然后使用 in 测试该对象是否具有 filter() 的属性
    猜你喜欢
    • 2018-06-24
    • 1970-01-01
    • 2017-09-09
    • 2012-02-27
    • 2021-09-26
    • 1970-01-01
    • 2019-07-30
    • 2014-10-08
    • 1970-01-01
    相关资源
    最近更新 更多