Какая хорошая математическая реализация в JavaScript?
Где хорошая реализация математических наборов для JavaScript? Он должен включать эффективные реализации пересечения, объединения, дополнения и (для бонусных точек) декартова произведения.
Нет, это не домашнее задание. У меня есть юбикей, это USB-клавиатура, которая набирает последовательность, выбранную из 16 кодов клавиш, для ввода 128-битного одноразового пароля (otp). Чтобы сделать его более полезным, программное обеспечение должно обнаружить раскладку клавиатуры на основе созданных символов и сопоставить эти символы с тем, что они будут в макете "us" для совместимости с существующим бэкэнд.
Итак, у меня есть 93 разных последовательности из 16 символов, представляющих все, что юбикеи могут вводить в каждом из 430 раскладок клавиатуры. (Многие макеты одинаковы для этой цели.) Возможные сопоставления для определенного otp - это каждая 16-символьная последовательность, содержащая каждый символ в otp.
Чтобы найти это эффективно, я использую обратный индекс, отображающий каждый возможный символ в список раскладок клавиатуры, которые используют этот символ. Ответ - это пересечение каждой записи обратного индекса для каждого уникального символа в ОТП. Это почти всегда заканчивается ровно одним элементом.
Было бы проще написать этот кросс-браузер с хорошей реализацией Set()
.
Код пока находится в http://dingoskidneys.com/~dholth/yubikey/
Ответы
Ответ 1
Я не знаю каких-либо существующих реализаций, но если ваши элементы набора являются строками (или имеют уникальное строковое представление), вы можете легко использовать объекты 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 set
или set.hasOwnProperty(item)
вместо set[item] === true
, но явно указав для true
, вы автоматически игнорируете любые функции, которые могут быть прикреплены к объекту (в случае, если кто-то изменил Object.prototype, или это не простой объект).
Ответ 2
Используя jPaq или другую библиотеку JavaScript, которая реализует функции Array.prototype.reduce и Array.prototype.forEach, вы можете создайте декартовую функцию продукта, которая принимает два или более массивов. Вот код для функции, которая вычисляет декартово произведение двух или более массивов:
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. Кстати, чтобы не плагиат, я понял, как использовать сокращение от этого сообщения.
Ответ 3
Используя Underscore метод уменьшения.
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); })
);
}, []);
}, [[]]);
}
Ответ 4
Sylvester - хорошая библиотека для создания векторной и матричной математики в Javascript. Это единственная математическая библиотека, о которой я могу сейчас подумать.
Ответ 5
Мне лично нравится, как это делается в jPaq (http://jpaq.org/documentation/Arrays+as+Sets/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 делает это так, что вам не нужно загружать лишние вещи, которые вы не будете использовать в любом случае.
Ответ 6
Я сделал JavaScript Установить реализацию, в основном касающуюся эффективных операций difference
, intersection
и union
. Он доступен в GitHub. Вилки и новые операции очень приветствуются!: -)
Ответ 7
В программе, вызвавшей этот вопрос, набор - это массив и пересечение -
s = [1,2,3];
q = [3,4,5];
sq = s.filter(function(x) {
return q.indexOf(x) >= 0;
});
Конечно, это не работает, т.е.