6

私は現在、eval()関数を使用してブール式を評価する必要があるJSルールエンジンを作成しています。

まず、次のような方程式を作成します。

var equation = "relation.relatedTrigger.previousValue" + " " + relation.operator +
        " " + "relation.value";

Relation.relatedTrigger.previousValueは、比較したい値です。

Relation.operatorは演算子です( "=="、 "!="、<=、 "<"、 ">"、> = "のいずれか)。

Relation.valueは、比較したい値です。

次に、この文字列をeval関数に渡すだけで、trueまたはfalseが返されます。

return eval(equation);

これは、(単語と数字を使用して)完全に正常に機能するか、>=と<=を除くすべての演算子で機能します。例:方程式を評価する場合:

relation.relatedTrigger.previousValue <= 100

previousValue = 0、1、10、100およびすべての負の数の場合はtrueを返しますが、その間のすべての場合はfalseを返します。

私の質問に答えるか、別の解決策を見つけるのを手伝ってくれる人の助けをいただければ幸いです。

よろしく、

Augier。

PS eval()関数の不安定さについてのスピーチは必要ありません。Relation.relatedTrigger.previousValueに指定された値はすべて事前定義されています。

編集:これが完全な機能です:

function evaluateRelation(relation)
{
console.log("Evaluating relation")
var currentValue;

//if multiple values
if(relation.value.indexOf(";") != -1)
{
    var values = relation.value.split(";");
    for (x in values)
    {

        var equation = "relation.relatedTrigger.previousValue" + " " + relation.operator +
        " " + "values[x]";
        currentValue = eval(equation);
        if (currentValue)
            return true;
    }
    return false;
}

//if single value
else
{
    //Evaluate the relation and get boolean
    var equation = "relation.relatedTrigger.previousValue" + " " + relation.operator +
        " " + "relation.value";
        console.log("relation.relatedTrigger.previousValue " + relation.relatedTrigger.previousValue);
    console.log(equation);
    return eval(equation);
}
}

回答:以下のKennyTMによって提供されます。文字列の比較は機能しません。数値への変換が必要でした。

4

3 に答える 3

5

取得方法は示していませんrelation.relatedTrigger.previousValueが、この変数の型はまだ文字列だと思います。この場合、右側は代わりに文字列として扱われます。文字列の比較は、あなたが言及したすべての特性に一致します。

>>> '-213' <= '100'
true
>>> '0' <= '100'
true
>>> '1' <= '100'
true
>>> '2' <= '100'
false
>>> '10' <= '100'
true
>>> '13' <= '100'
false

あなたは数であることを確認する必要がありますrelation.relatedTrigger.previousValue。1つの解決策は、比較で単項+演算子を使用することです。

+relation.relatedTrigger.previousValue <= 100

これはとは何の関係もありませんeval。問題は、Javascriptでの過度にリベラルな暗黙の変換です。


編集:ちなみに、evalの代わりに、関数の辞書を使用することもできます。これはより速く、より安全です。http://jsperf.com/eval-vs-function-mapを参照してください。

var fmap = {
    '>=': function(a, b) { return a >= b; },
    ...
};

fmap[relation.operator](+relation.relatedTrigger.previousValue, 
                        +relation.value);
于 2012-09-21T09:26:59.947 に答える
1

数字ではなく文字列を比較しています。

relation.relatedTrigger.previousValuerelation.valueが数字であることを確認してください。

"11"> "100":アルファベット順に続く11からです。100

番号順に11<100。

于 2012-09-21T09:34:32.153 に答える
0
var relation = {'relatedTrigger':{'previousValue':"7"}, 'operator':'<=', 'value': "100"};

var equation = "parseFloat(relation.relatedTrigger.previousValue)" + " " + relation.operator + 
    " " + "parseFloat(relation.value)"; 

alert(equation + ", " + eval(equation));

これは事実上最終的な結果であり、文字列ではなく数値を確実に渡すための追加の手順が機能しているようです。

于 2012-09-21T09:36:50.937 に答える