是否有一种有效的方法来对数组数据(Javascript)执行高级“分面”过滤?
Is there an effective way to perform the advanced “faceted” filtering for the array data (with Javascript)?
我有一个数组:
var arr = [
["a", "b", "d"],
["k", "b", "n", "a"],
["k", "a", "e", "c"],
["k", "b", "e"],
["b", "c"]
]
我想提取仅在包含 "a" 和 "b" 的子数组中出现的所有值。对于上面的示例,这些将是 ["d", "k", "n"]
.
当然,有一个明显的方法可以达到这个结果:
新建array/object,我们命名为result
。
迭代 arr
。对于每个子数组,检查它是否包含 ["a", "b"]
的所有项目 - 如果是,则将其所有项目(可能除了 "a" 和 "b",但没关系)添加到 result
(但在添加之前,我们可能想检查 result
中是否已经存在具有相同值的项目);如果没有,则跳过。
如果我们在添加之前没有检查我们的项目,那么从 result
中删除所有重复项。如果 result
按字母顺序排序,现在应该是 ["d", "k", "n"]
。
问题是这种方式似乎 太 缓慢且无效,特别是如果我在 arr
中有很多子数组并且没有太多不同的值:我会每次修改 ["a", "b"]
时都强制重复该过程!
构建这样的结构很容易:
var s = [
{value: "a", siblings: ["b", "c", "d", "e", "k", "n"]},
{value: "b", siblings: ["a", "c", "d", "e", "k", "n"]},
{value: "c", siblings: ["a", "b", "e", "k"]},
{value: "d", siblings: ["a", "b"]},
{value: "e", siblings: ["a", "b", "c", "k"]},
{value: "k", siblings: ["a", "b", "c", "e", "n"]},
{value: "n", siblings: ["a", "b", "k"]}
]
但是,如果我现在过滤所有在其 siblings
键中包含 ["a", "b"]
每个值的对象,我会得到 ["d", "e", "k", "n"]
,这是错误的。
所以,我想问:是否有可能构建一些看起来像
的智能“索引”结构
var s = [
{value: "a", data: indexdata1},
{value: "b", data: indexdata2},
{value: "c", data: indexdata3},
{value: "d", data: indexdata4},
{value: "e", data: indexdata5},
{value: "k", data: indexdata6},
{value: "n", data: indexdata7}
]
这样当我做 someFunc(s, ["a", "b"])
时,它 returns [{value: "d"}, {value: "k"}, {value: "n"}]
?无论如何,在 Javascript 中,什么可以被视为 有效 解决此问题的方法?是否有具有此类功能的现有库?
请注意,此问题与 eikes.github.io/facetedsearch 所做的不同(或者我找不到修改其代码的方法)。
采用不同方法的提案。不是对单个 items/letters 的视图,而是用找到的字母数组的索引组织一个对象 s
。
然后通过计数和过滤仅具有给定搜索长度 (c
) 的字母来锐化它。使用 c
.
剩余索引中的字母构建一个新对象 r
从 r
中删除给定的字母,获取密钥,对其排序并 return 结果。
function x(s, array) {
var c = {}, r = {};
array.forEach(function (a) {
s[a].forEach(function (b) {
c[b] = (c[b] || 0) + 1;
});
});
document.write('<pre>c: ' + JSON.stringify(c, 0, 4) + '</pre>');
Object.keys(c).filter(function (a) {
return c[a] === array.length;
}).forEach(function (a) {
arr[a].forEach(function (b) {
r[b] = true;
});
});
document.write('<pre>r: ' + JSON.stringify(r, 0, 4) + '</pre>');
array.forEach(function (a) {
delete r[a];
});
document.write('<pre>r: ' + JSON.stringify(r, 0, 4) + '</pre>');
return Object.keys(r).sort();
}
var arr = [
["a", "b", "d"],
["k", "b", "n", "a"],
["k", "a", "e", "c"],
["k", "b", "e"],
["b", "c"]
],
s = arr.reduce(function (r, a, i) {
a.forEach(function (b) {
r[b] = r[b] || [];
r[b].push(i);
});
return r;
}, {});
document.write('<pre>s: ' + JSON.stringify(s, 0, 4) + '</pre>');
document.write('<pre>result: ' + JSON.stringify(x(s, ['a', 'b']), 0, 4) + '</pre>');
我有一个数组:
var arr = [
["a", "b", "d"],
["k", "b", "n", "a"],
["k", "a", "e", "c"],
["k", "b", "e"],
["b", "c"]
]
我想提取仅在包含 "a" 和 "b" 的子数组中出现的所有值。对于上面的示例,这些将是 ["d", "k", "n"]
.
当然,有一个明显的方法可以达到这个结果:
新建array/object,我们命名为
result
。迭代
arr
。对于每个子数组,检查它是否包含["a", "b"]
的所有项目 - 如果是,则将其所有项目(可能除了 "a" 和 "b",但没关系)添加到result
(但在添加之前,我们可能想检查result
中是否已经存在具有相同值的项目);如果没有,则跳过。如果我们在添加之前没有检查我们的项目,那么从
result
中删除所有重复项。如果result
按字母顺序排序,现在应该是["d", "k", "n"]
。
问题是这种方式似乎 太 缓慢且无效,特别是如果我在 arr
中有很多子数组并且没有太多不同的值:我会每次修改 ["a", "b"]
时都强制重复该过程!
构建这样的结构很容易:
var s = [
{value: "a", siblings: ["b", "c", "d", "e", "k", "n"]},
{value: "b", siblings: ["a", "c", "d", "e", "k", "n"]},
{value: "c", siblings: ["a", "b", "e", "k"]},
{value: "d", siblings: ["a", "b"]},
{value: "e", siblings: ["a", "b", "c", "k"]},
{value: "k", siblings: ["a", "b", "c", "e", "n"]},
{value: "n", siblings: ["a", "b", "k"]}
]
但是,如果我现在过滤所有在其 siblings
键中包含 ["a", "b"]
每个值的对象,我会得到 ["d", "e", "k", "n"]
,这是错误的。
所以,我想问:是否有可能构建一些看起来像
的智能“索引”结构 var s = [
{value: "a", data: indexdata1},
{value: "b", data: indexdata2},
{value: "c", data: indexdata3},
{value: "d", data: indexdata4},
{value: "e", data: indexdata5},
{value: "k", data: indexdata6},
{value: "n", data: indexdata7}
]
这样当我做 someFunc(s, ["a", "b"])
时,它 returns [{value: "d"}, {value: "k"}, {value: "n"}]
?无论如何,在 Javascript 中,什么可以被视为 有效 解决此问题的方法?是否有具有此类功能的现有库?
请注意,此问题与 eikes.github.io/facetedsearch 所做的不同(或者我找不到修改其代码的方法)。
采用不同方法的提案。不是对单个 items/letters 的视图,而是用找到的字母数组的索引组织一个对象 s
。
然后通过计数和过滤仅具有给定搜索长度 (c
) 的字母来锐化它。使用 c
.
r
从 r
中删除给定的字母,获取密钥,对其排序并 return 结果。
function x(s, array) {
var c = {}, r = {};
array.forEach(function (a) {
s[a].forEach(function (b) {
c[b] = (c[b] || 0) + 1;
});
});
document.write('<pre>c: ' + JSON.stringify(c, 0, 4) + '</pre>');
Object.keys(c).filter(function (a) {
return c[a] === array.length;
}).forEach(function (a) {
arr[a].forEach(function (b) {
r[b] = true;
});
});
document.write('<pre>r: ' + JSON.stringify(r, 0, 4) + '</pre>');
array.forEach(function (a) {
delete r[a];
});
document.write('<pre>r: ' + JSON.stringify(r, 0, 4) + '</pre>');
return Object.keys(r).sort();
}
var arr = [
["a", "b", "d"],
["k", "b", "n", "a"],
["k", "a", "e", "c"],
["k", "b", "e"],
["b", "c"]
],
s = arr.reduce(function (r, a, i) {
a.forEach(function (b) {
r[b] = r[b] || [];
r[b].push(i);
});
return r;
}, {});
document.write('<pre>s: ' + JSON.stringify(s, 0, 4) + '</pre>');
document.write('<pre>result: ' + JSON.stringify(x(s, ['a', 'b']), 0, 4) + '</pre>');