JavaScript 中什么是好的数学集合实现?

发布于 2024-08-02 05:43:32 字数 616 浏览 5 评论 0原文

哪里有一个好的 JavaScript 数学集合实现?它应该包括交集、并集、补集和(奖励点)笛卡尔积的有效实现。

不,这不是家庭作业。我有一个 yubikey,它是一个 USB 键盘,可以输入从 16 个键码中选择的序列来输入 128 位一次性密码 (otp)。为了使其更有用,软件应根据生成的字符检测键盘布局,并将这些字符映射回“us”布局中的内容,以便与现有后端兼容。

因此,我有 93 个不同的 16 个字符序列,代表 yubikey 在 430 种键盘布局中的每一种中可以输入的所有内容。 (为此目的,许多布局都是相同的。)特定 otp 的可能映射是包含 otp 中每个字符的每个 16 个字符序列。

为了有效地找到这一点,我使用反向索引将每个可能的字符映射到使用该字符的键盘布局列表。答案是 otp 中每个唯一字符的反向索引的每个条目的交集。这几乎总是以恰好 1 个元素结束。

通过良好的 Set() 实现来编写这个跨浏览器会更容易。

到目前为止的代码位于 http://dingoskidneys.com/~dholth/yubikey/

Where is a good mathematical sets implementation for JavaScript? It should include efficient implementations of intersection, union, complement, and (for bonus points) the Cartesian product.

No, it's not homework. I got a yubikey, it is a USB keyboard that types a sequence chosen from 16 keycodes to type a 128-bit one time password (otp). To make it more useful, software should detect the keyboard layout based on the characters produced and map those characters back to what they would be in the "us" layout for compatibility with the existing backend.

So I've got 93 different sequences of 16 characters representing everything the yubikey can type in each of 430 keyboard layouts. (Many layouts are the same for this purpose.) The possible mappings for a particular otp is each 16-character sequence that contains every character in the otp.

To find this efficiently I use a reverse index mapping each possible character to a list of the keyboard layouts that use that character. The answer is the intersection of each entry of the reverse index for each unique character in the otp. This almost always winds up with exactly 1 element.

It would be easier to write this cross-browser with a good implementation of Set().

Code so far is at http://dingoskidneys.com/~dholth/yubikey/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

嗼ふ静 2024-08-09 05:43:32

通过使用 jPaq 或其他实现 Array.prototype.reduce 和 Array.prototype.forEach 函数的 JavaScript 库,您可以创建接受两个或多个数组的笛卡尔积函数。以下是计算两个或多个数组的笛卡尔积的函数的代码:

function cartesianProductOf() {
  return Array.prototype.reduce.call(arguments, function(a, b) {
    var ret = [];
    a.forEach(function(a) {
      b.forEach(function(b) {
        ret.push(a.concat([b]));
      });
    });
    return ret;
  }, [[]]);
}

就库中的情况而言,我愿意接受有关函数命名的建议,以便我可以将其添加到 jPaq。顺便说一下,为了不抄袭,我确实从这个中得到了使用reduce的想法发布

By using jPaq or another JavaScript library that implements the Array.prototype.reduce and Array.prototype.forEach functions, you can create a cartesian product function that accepts two or more arrays. Here is code for a function that computes the cartesian product of two or more arrays:

function cartesianProductOf() {
  return Array.prototype.reduce.call(arguments, function(a, b) {
    var ret = [];
    a.forEach(function(a) {
      b.forEach(function(b) {
        ret.push(a.concat([b]));
      });
    });
    return ret;
  }, [[]]);
}

As far as this being in a library, I am open to suggestions for the naming of the function so that I can add it into jPaq. By the way, so as not to plagiarize, I did get the idea of using reduce from this post.

北城半夏 2024-08-09 05:43:32

我不知道任何现有的实现,但如果您的集合元素是字符串(或具有唯一的字符串表示形式),您可以非常轻松地使用 JavaScript 对象。元素将是对象属性,值可以是任何内容。

// Make a set from an array of elements
function makeSet(items) {
    var set = {};
    for (var i = 0; i < items.length; i++) {
        set[items[i]] = true;
    }
    return set;
}

function copyInto(s, copy) {
    for (var item in s) {
        if (s[item] === true) {
            copy[item] = true;
        }
    }
}

function union(s1, s2) {
    var u = {};
    copyInto(s1, u);
    copyInto(s2, u);
    return u;
}

function intersection(s1, s2) {
    var i = {};
    for (var item in s1) {
        if (s1[item] === true && s2[item] === true) {
            i[item] = true;
        }
    }
    return i;
}

function difference(s1, s2) {
    var diff = {};
    copyInto(s1, diff);
    for (var item in s2) {
        if (s2[item] === true) {
            delete diff[item];
        }
    }
    return diff;
}

// etc.

您还可以使用 item in setset.hasOwnProperty(item) 而不是 set[item] === true,但通过 for 检查true 显式地,您会自动忽略可能附加到该对象的任何函数(以防有人修改了 Object.prototype,或者它不是一个普通对象)。

I don't know of any existing implementations, but if your set elements are strings (or have a unique string representation) you can use JavaScript objects pretty easily. The elements would be the object properties, and the value could be anything.

// Make a set from an array of elements
function makeSet(items) {
    var set = {};
    for (var i = 0; i < items.length; i++) {
        set[items[i]] = true;
    }
    return set;
}

function copyInto(s, copy) {
    for (var item in s) {
        if (s[item] === true) {
            copy[item] = true;
        }
    }
}

function union(s1, s2) {
    var u = {};
    copyInto(s1, u);
    copyInto(s2, u);
    return u;
}

function intersection(s1, s2) {
    var i = {};
    for (var item in s1) {
        if (s1[item] === true && s2[item] === true) {
            i[item] = true;
        }
    }
    return i;
}

function difference(s1, s2) {
    var diff = {};
    copyInto(s1, diff);
    for (var item in s2) {
        if (s2[item] === true) {
            delete diff[item];
        }
    }
    return diff;
}

// etc.

You could also use item in set or set.hasOwnProperty(item) instead of set[item] === true, but checking by for true explicitly, you automatically ignore any functions that might be attached to the object (in case someone modified Object.prototype, or it's not a plain object).

最近可好 2024-08-09 05:43:32

使用Underscore的reduce方法。

function cartesianProductOf(){
    return _.reduce(arguments, function(mtrx, vals){
        return _.reduce(vals, function(array, val){
            return array.concat(
                _.map(mtrx, function(row){ return row.concat(val); })
            );
        }, []);
    }, [[]]);
}

Using Underscore's reduce method.

function cartesianProductOf(){
    return _.reduce(arguments, function(mtrx, vals){
        return _.reduce(vals, function(array, val){
            return array.concat(
                _.map(mtrx, function(row){ return row.concat(val); })
            );
        }, []);
    }, [[]]);
}
时光病人 2024-08-09 05:43:32

Sylvester 是一个很好的库,用于在 Javascript 中进行向量和矩阵数学运算。这是我现在能想到的唯一的数学库。

Sylvester is a good library for doing vector and matrix Math in Javascript. It's the only Math library I can think of right now.

三生一梦 2024-08-09 05:43:32

我个人喜欢 jPaq 中的实现方式(http://jpaq.org/documentation/数组+as+集合/1.0/)。以下是我测试成功的三个示例:

alert([1,2,3,4,5].subtract([2,3,5]));  // evaluates to [1,4]
alert([1,2,5].union([1,3,4,5]));  // evaluates to [1,2,5,3,4]
alert([1,2,3,5].intersect([0,1,2,4,6]));  // evaluates to [1,2]

jPaq 的好处是您可以下载代码对于这三个函数。 jPaq 做到了这一点,这样您就不必下载您不会使用的额外内容。

I personally like how it is done in jPaq (http://jpaq.org/documentation/Arrays+as+Sets/1.0/). Here are three examples that I tested out successfully:

alert([1,2,3,4,5].subtract([2,3,5]));  // evaluates to [1,4]
alert([1,2,5].union([1,3,4,5]));  // evaluates to [1,2,5,3,4]
alert([1,2,3,5].intersect([0,1,2,4,6]));  // evaluates to [1,2]

The nice thing about jPaq is the fact that you can just download the code for these three functions. jPaq makes it so you don't have to download the extra stuff that you will not be using anyway.

相守太难 2024-08-09 05:43:32

我已经完成了一个 JavaScript Set 实现,主要关注高效的差异交集并集操作。它位于 GitHub。非常欢迎分叉和新操作! :-)

I've done a JavaScript Set implementation mainly concerned with efficient difference, intersection and union operations. It's available at GitHub. Forks and new operations are very welcome! :-)

野却迷人 2024-08-09 05:43:32

在引发这个问题的程序中,集合是数组,相交是

s = [1,2,3];
q = [3,4,5];
sq = s.filter(function(x) {
    return q.indexOf(x) >= 0;
});

当然,它在ie中不起作用。

In the program that sparked this question, a set is an Array and intersect is

s = [1,2,3];
q = [3,4,5];
sq = s.filter(function(x) {
    return q.indexOf(x) >= 0;
});

Of course it doesn't work in ie.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文