Преобразование String с алгебраическими операциями в целое число / float в JavaScript [duplicate]

ffmpeg не предустановлен (в значительной степени просто ImageMagick); чтобы увидеть, что именно установлено, проверьте файл Docker здесь: https://github.com/GoogleCloudPlatform/nodejs-docker/blob/master/runtime-image/Dockerfile .

Однако вы можете загружать произвольные двоичные файлы при загрузке кода с помощью gcloud beta functions deploy, потому что загружается все в текущем каталоге (кроме node_modules).

Примечание: у вас есть только доступ к записи на диск в /tmp/.

Вариант 1: использовать модуль ffmpeg-static npm

ffmpeg-static - модуль npm, который строит правильный двоичный файл ffmpeg на основе текущей системы во время npm install. Поскольку облачные функции строят ваш код в облаке, он построит правильный двоичный файл ffmpeg.

https://github.com/eugeneware/ffmpeg-static

Вы можете увидеть это в действии в Облачных функциях для примеров Firebase repo .

const ffmpeg = require('fluent-ffmpeg');
const ffmpeg_static = require('ffmpeg-static');

var cmd = ffmpeg('/tmp/video.avi')
  .setFfmpegPath(ffmpeg_static.path)
  .videoBitrate(1024)
  .videoCodec('divx')
  .format('avi')
  .on('end', () => {
    // ...
  })
  .on('error', err => {
    console.error(err);
  })
  .save('/tmp/file-out.avi');

( Спасибо Даниэлю Лессе за то, что он указал на этот модуль в его ответе .)

Вариант 2: загрузить свой собственный двоичный файл

Вы можете включить двоичный файл ffmpeg как часть загрузите и затем запустите команду оболочки, используя что-то вроде child_process.exec . Вам понадобится двоичный файл ffmpeg, который скомпилирован для целевой платформы (Debian / jessie).

Список файлов с предварительно скомпилированным ffmpeg binary

./
../
index.js
ffmpeg

Затем запустите, например, gcloud beta functions deploy myFunc --trigger-http

index.js

var exec = require('child_process').exec;
var cmd = 'ffmpeg -i /tmp/myvideo.mp4 /tmp/image-%d.jpg';

exec(cmd, function(error, stdout, stderr) {
  // command output is in stdout
});

52
задан nbrooks 4 February 2013 в 12:51
поделиться

14 ответов

Я в конце концов пошел на это решение, которое работает для суммирования положительных и отрицательных целых чисел (и с небольшой модификацией регулярного выражения будет работать и для десятичных знаков):

function sum(string) {
  return (string.match(/^(-?\d+)(\+-?\d+)*$/)) ? string.split('+').stringSum() : NaN;
}   

Array.prototype.stringSum = function() {
    var sum = 0;
    for(var k=0, kl=this.length;k<kl;k++)
    {
        sum += +this[k];
    }
    return sum;
}

Я не конечно, если это быстрее, чем eval (), но поскольку я должен выполнять операцию много раз, мне гораздо удобнее запускать этот скрипт, чем создавать множество экземпляров javascript-компилятора

2
ответ дан wheresrhys 20 August 2018 в 14:42
поделиться
  • 1
    Хотя return нельзя использовать внутри выражения, sum("+1") возвращает NaN . – Gumbo 6 March 2010 в 12:54
  • 2
    Всегда предопределяйте, должно ли возвращение иметь или не может войти в тройное выражение. Я хотел бы исключить & quot; + 1 & quot; потому что, хотя он «должен» оцениваться как число, на самом деле это не пример математической суммы в повседневном смысле. Мой код предназначен для оценки и фильтрации допустимых строк. – wheresrhys 6 March 2010 в 13:12

Попробуйте nerdamer

var result = nerdamer('12+2+PI').evaluate();
document.getElementById('text').innerHTML = result.text();
<script src="http://nerdamer.com/js/nerdamer.core.js"></script>
<div id="text"></div>

2
ответ дан ArchHaskeller 20 August 2018 в 14:42
поделиться

Я создал BigEval для этой же цели. При решении выражений он выполняет точно такие же, как Eval(), и поддерживает такие операторы, как%, ^, & amp ;, ** (мощность) и! (факториал). Вы также можете использовать функции и константы (или сказать переменные) внутри выражения. Выражение решается в порядке PEMDAS , который является общим для языков программирования, включая JavaScript.

var Obj = new BigEval();
var result = Obj.exec("5! + 6.6e3 * (PI + E)"); // 38795.17158152233
var result2 = Obj.exec("sin(45 * deg)**2 + cos(pi / 4)**2"); // 1
var result3 = Obj.exec("0 & -7 ^ -7 - 0%1 + 6%2"); //-7

Также можно использовать библиотеки Big Number для арифметики, если вы имея дело с числами с произвольной точностью.

6
ответ дан Avi 20 August 2018 в 14:42
поделиться

Я считаю, что parseInt и ES6 могут быть полезны в этой ситуации

==> следующим образом:

let func = (str) => {
let arr = str.split("");
return `${Number(arr[0]) + parseInt(arr[1] + Number(arr[2]))}`};
console.log(func("1+1"));

Основной Дело в том, что parseInt анализирует число с оператором. Код может быть изменен с учетом соответствующих потребностей.

1
ответ дан fuser 20 August 2018 в 14:42
поделиться

Кто-то должен разобрать эту строку. Если это не интерпретатор (через eval), то это должен быть вам, написание процедуры разбора для извлечения чисел, операторов и всего, что вы хотите поддержать в математическом выражении.

So , нет, нет (простого) пути без eval. Если вы беспокоитесь о безопасности (потому что ввод, который вы обрабатываете, не из источника, которым вы управляете), возможно, вы можете проверить формат ввода (через белый фильтр регулярных выражений), прежде чем передавать его на eval?

17
ответ дан Greg Hewgill 20 August 2018 в 14:42
поделиться
  • 1
    Это не безопасность, которая меня беспокоит (у меня уже есть регулярное выражение для задания), это больше нагрузки на браузер, так как мне приходится обрабатывать много строк, подобных этому. Может ли пользовательский парсер быть быстрее, чем eval ()? – wheresrhys 16 February 2010 в 21:24
  • 2
    @wheresrhys: Почему вы думаете, что ваш парсер, написанный в JS, будет быстрее, чем предоставленная система (оптимизирована, возможно, написана на C или C ++)? – Mehrdad Afshari 16 February 2010 в 21:41
  • 3
    eval - самый быстрый способ сделать это. Однако для обеспечения безопасности обычно недостаточно регулярного выражения. – levik 16 February 2010 в 21:44
  • 4
    @wheresrhys: Почему у вас много таких строк? Они генерируются программой? Если это так, самым простым способом является вычисление результата до преобразования в строки. В противном случае это время write-your-own-parser. – Phil H 2 May 2012 в 13:58

Вот алгоритмическое решение, подобное jMichael, которое циклически перемещает символ выражения по символу и постепенно отслеживает left / operator / right. Функция накапливает результат после каждого поворота, который находит символ оператора. Эта версия поддерживает только операторы «+» и «-», но записывается для расширения с другими операторами. Примечание: перед циклом мы устанавливаем 'currOp' в '+', потому что предположим, что выражение начинается с положительного поплавка. Фактически, в целом, я делаю предположение, что ввод аналогичен тому, что исходит от калькулятора.

function calculate(exp) {
  const opMap = {
    '+': (a, b) => { return parseFloat(a) + parseFloat(b) },
    '-': (a, b) => { return parseFloat(a) - parseFloat(b) },
  };
  const opList = Object.keys(opMap);

  let acc = 0;
  let next = '';
  let currOp = '+';

  for (let char of exp) {
    if (opList.includes(char)) {
      acc = opMap[currOp](acc, next);
      currOp = char;
      next = '';
    } else {
      next += char;
    } 
  }

  return currOp === '+' ? acc + parseFloat(next) : acc - parseFloat(next);
}
0
ответ дан internetross 20 August 2018 в 14:42
поделиться

Я пошел искать библиотеки JavaScript для оценки математических выражений и нашел этих двух перспективных кандидатов:

  • JavaScript Expression Evaluator : Меньше и, надеюсь, более легкий. Позволяет алгебраические выражения, подстановки и ряд функций.
  • mathjs : Позволяет создавать комплексные числа, матрицы и единицы.
Создано для использования как в браузере JavaScript, так и в Node.js.
6
ответ дан Itangalo 20 August 2018 в 14:42
поделиться
  • 1
    Теперь я тестировал JavaScript Expression Evaluator, и, похоже, он качается. (mathjs, вероятно, тоже скатывается, но для моих целей это кажется слишком большим, и мне также нравится возможность замены в JSEE.) – Itangalo 12 February 2014 в 15:20

Это небольшая функция, которую я собрал сейчас, чтобы решить эту проблему - она ​​создает выражение, анализируя строку по одному персонажу за раз (на самом деле это довольно быстро). Это займет какое-либо математическое выражение (ограничивается только +, -, *, / операторами) и возвращает результат. Он также может обрабатывать отрицательные значения и операции с неограниченным числом.

Единственное, что нужно сделать, это убедиться, что он вычисляет * & amp; / до + & amp; -. Добавит эту функциональность позже, но пока это делает то, что мне нужно ...

/**
* Evaluate a mathematical expression (as a string) and return the result
* @param {String} expr A mathematical expression
* @returns {Decimal} Result of the mathematical expression
* @example
*    // Returns -81.4600
*    expr("10.04+9.5-1+-100");
*/ 
function expr (expr) {

    var chars = expr.split("");
    var n = [], op = [], index = 0, oplast = true;

    n[index] = "";

    // Parse the expression
    for (var c = 0; c < chars.length; c++) {

        if (isNaN(parseInt(chars[c])) && chars[c] !== "." && !oplast) {
            op[index] = chars[c];
            index++;
            n[index] = "";
            oplast = true;
        } else {
            n[index] += chars[c];
            oplast = false;
        }
    }

    // Calculate the expression
    expr = parseFloat(n[0]);
    for (var o = 0; o < op.length; o++) {
        var num = parseFloat(n[o + 1]);
        switch (op[o]) {
            case "+":
                expr = expr + num;
                break;
            case "-":
                expr = expr - num;
                break;
            case "*":
                expr = expr * num;
                break;
            case "/":
                expr = expr / num;
                break;
        }
    }

    return expr;
}
4
ответ дан jMichael 20 August 2018 в 14:42
поделиться

Попробуйте AutoCalculator https://github.com/JavscriptLab/autocalculate Вычислить значение входов и вывод с помощью селекторных выражений

Просто добавьте атрибут для ввода вывода, ac = "(# firstinput + # secondinput)"

Нет необходимости в какой-либо инициализации, просто добавьте только атрибут data-ac. Он будет автоматически обнаруживать динамически добавленные элементы

FOr add 'Rs' с выходом только добавить внутри фигурных скобок данных-ac = "{Rs} (# firstinput + # secondinput)"

1
ответ дан Justin Jose 20 August 2018 в 14:42
поделиться

// Вы можете делать + или - легко:

function addbits(s){
    var total= 0, s= s.match(/[+\-]*(\.\d+|\d+(\.\d+)?)/g) || [];
    while(s.length){
        total+= parseFloat(s.shift());
    }
    return total;
}

var string='1+23+4+5-30';
addbits(string)

Более сложная математика делает eval более привлекательной и, конечно, проще писать.

16
ответ дан kennebec 20 August 2018 в 14:42
поделиться
  • 1
    +1 - Вероятно, немного более общий, чем я, но это не сработает для моей ситуации, поскольку у меня может быть что-то вроде 1 + -2, и я хочу, чтобы регулярное выражение также исключало неверные утверждения (я думаю, что-то вроде «+ 3 + 4 +») – wheresrhys 6 March 2010 в 13:02
  • 2
    Человек! ... Это спасло меня около 10 килограммов тяжелого поиска Google ... Блестяще! – ErickBest 30 January 2014 в 15:54
  • 3
    Я опубликовал ниже обновленный ответ с более коротким регулярным выражением и позволяющий пробелы между операторами – Stefan Gabos 31 May 2017 в 10:22

Вы можете использовать библиотеку JavaScript Expression Evaluator , которая позволяет вам делать такие вещи, как:

Parser.evaluate("2 ^ x", { x: 3 });

Или mathjs , что позволяет например:

math.eval('sin(45 deg) ^ 2');

Я решил выбрать mathjs для одного из моих проектов.

49
ответ дан Rafael Vega 20 August 2018 в 14:42
поделиться

Я недавно сделал это в C # (без Eval () для нас ...), оценив выражение в Reverse Polish Notation (это легкий бит). Трудная часть на самом деле разбирает строку и превращает ее в обратную польскую нотацию. Я использовал алгоритм Shunting Yard, потому что есть отличный пример в Википедии и псевдокоде. Мне было очень просто реализовать оба варианта, и я бы рекомендовал, если вы еще не нашли решение или смотрите на альтернативы.

6
ответ дан RichK 20 August 2018 в 14:42
поделиться
const getAddition = (str) => {
  return str.split('+').reduce((total, num) => (total + num * 1), 0);
};

const addition = getAddition('1+1');

сложение равно 2.

0
ответ дан Rushikesh Bharad 20 August 2018 в 14:42
поделиться

Альтернатива отличному ответу @kennebec, используя более короткое регулярное выражение и позволяющее пробелы между операторами

function addbits(s) {
    var total = 0;
    s = s.replace(/\s/g, '').match(/[+\-]?([0-9\.\s]+)/g) || [];
    while(s.length) total += parseFloat(s.shift());
    return total;
}

Использовать его как

addbits('5 + 30 - 25.1 + 11');

Обновить

Вот более оптимизированная версия

function addbits(s) {
    return (s.replace(/\s/g, '').match(/[+\-]?([0-9\.]+)/g) || [])
        .reduce(function(sum, value) {
            return parseFloat(sum) + parseFloat(value);
        });
}
4
ответ дан Stefan Gabos 20 August 2018 в 14:42
поделиться
  • 1
    Это идеально, если вам нужно только сложение и вычитание. Так мало кода, столько продуктов! Будьте уверены, он используется для хорошего :) – Ultroman the Tacoman 17 July 2017 в 12:19
Другие вопросы по тегам:

Похожие вопросы: