【问题标题】:Is there an effective way to perform the advanced “faceted” filtering for the array data (with Javascript)?有没有一种有效的方法来对数组数据执行高级“分面”过滤(使用 Javascript)?
【发布时间】:2016-01-08 06:43:36
【问题描述】:

我有一个数组:

var arr = [
["a", "b", "d"],
["k", "b", "n", "a"],
["k", "a", "e", "c"],
["k", "b", "e"],
["b", "c"]
]  

我想提取仅出现在包含“a”和“b”的子数组中的所有值。对于上面的示例,这些将​​是 ["d", "k", "n"]
当然,有一个明显的方法可以达到结果:

  1. 创建新的数组/对象,我们将其命名为result

  2. 遍历arr。对于每个子数组,检查它是否包含["a", "b"] 的所有项目 - 如果是,则将其所有项目(可能除了“a”和“b”,但没关系)添加到result(但在添加之前,我们可能想检查result中是否已经存在具有相同值的项目;如果没有,则跳过。

  3. 如果我们在添加之前没有检查我们的项目,则从 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"]) 时,它会返回[{value: "d"}, {value: "k"}, {value: "n"}]?无论如何,什么可以被认为是在 Javascript 中解决此问题的一种有效方法?是否存在具有此类功能的库?
请注意,此问题与 eikes.github.io/facetedsearch 所做的不同(或者我找不到修改其代码的方法)。

【问题讨论】:

    标签: javascript faceted-search


    【解决方案1】:

    采用不同方法的提案。不是查看单个项目/字母,而是使用找到的字母数组的索引组织一个对象 s

    然后通过计数并仅过滤具有给定搜索长度 (c) 计数的字母来锐化它。使用c 剩余索引中的字母构建一个新对象r

    r中删除给定的字母,获取键,排序并返回结果。

    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>');

    【讨论】:

    • 谢谢,它似乎工作!在 Object.keys 中存储值...是的...这种方法更好...
    猜你喜欢
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多