我有两列的行:产品SKU和类别ID 我只需要返回产品SKU及其与cat_id列表匹配的cat_id 在SQL中将是:
SELECT SKU,cat_id FROM myTable where cat_id IN(my_huge cat_ids_list)
但是我需要使用Javascript从Tab标签返回数据。
很显然,我可以使用两个嵌套循环来完成此操作,但这将导致数百万次比较,而且速度太慢
如果我有30000个SKU,则可以与1000个cat_id相匹配,最坏的情况是要进行3000万次测试。
那么有没有一种聪明的算法方法可以在不需要太多测试的情况下更全局地对其进行过滤?
非常感谢
答案 0 :(得分:1)
对您的cat_ids列表使用哈希集,这可以进行恒定时间的遏制检查。不太熟悉javascript,但我相信Set
类型应该可以解决问题。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
答案 1 :(得分:1)
您不需要嵌套循环。使用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)