1

私は、いわゆる JavaScript の Name Value Lists から値を頻繁に解析していることに気づきました。

私は自分で作成した関数を使用しましたが、これはかなりうまく機能しましたが、プロトタイプ プロパティを試してみることにしました。うまくいくようですが、2番目の関数「nvlSet」が「醜い」ものだと思います。

あなたはそう思いますか?..もしそうなら、どうすればより「エレガントな」仕事をすることができると思いますか?

if(!String.prototype.nvlGet) {
    String.prototype.nvlGet = function(nme,def){
        return((rem0=new RegExp('(\\b|,)' + nme + '=([^\\b][^,]*)').exec(this)) ? rem0[2] : def);
    }
}
if(!String.prototype.nvlSet) {
    String.prototype.nvlSet = function(nme,val){
        var re0=new RegExp('(\\b' + nme + '=[^\\b][^,]*)');
        if(re0.test(this)) return(this.replace(re0,nme + "=" + val));
        re0.compile('(,' + nme + '=[^\\b][^,]*)');
        return(this.replace(re0,',' + nme + "=" + val));
    }
}

var lst='firstName=John,lastName=Smith,department=Sales';
alert(lst.nvlGet('firstName')); // John
alert(lst.nvlGet('surName','none')); // none
lst=lst.nvlSet('department','Research');
alert(lst.nvlGet('department','unknown')); // Research
alert(lst); // firstName=John,lastName=Smith,department=Research

また、次のような「二重割り当て」は避けたいと思います。

lst=lst.nvlSet('department','Research');

このようなものに:

lst.nvlSet('department','Research');

しかし、私はそれを行う方法を見つけることができませんでした。

4

3 に答える 3

2

私が提案するのは、nvls をオブジェクトにシリアライズおよびデシリアライズすることです。かなり単純な例は次のとおりです。

function deserialize(nvl) {
  var re = /(\w+)=(\w+)/g, matches, props = {};
  while (matches = re.exec(nvl)) {
    props[matches[1]] = matches[2];
  }
  return props;
}

function serialize(props) {
  var prop, nvl = [];
  for (prop in props) {
    if (props.hasOwnProperty(prop)) {
      nvl.push(prop + '=' + props[prop]);
    }
  }
  return nvl.join(',');
}

あなたの例は次のようになります。

var props = deserialize('firstName=John,lastName=Smith,department=Sales');
alert(props.firstName); // John
alert(props.surName); // undefined
props.department = 'Research';
alert(props.department); // Research
alert(serialize(props)); // firstName=John,lastName=Smith,department=Research
于 2012-10-10T23:43:50.670 に答える
1

文字列はjavascriptでは不変です。現在の文字列オブジェクトの内容を変更することはできません。そのため、文字列を操作するすべての文字列メソッドは、新しい文字列オブジェクトを返します。したがって、次の目的の構造:

lst.nvlSet('department','Research');

現在の文字列オブジェクトを変更したい場所は実行できません。

状態を保存する独自の通常のオブジェクトを作成し、次のようにその状態を取得または設定するメソッドを作成できます。

function nvl(str) {
    this.data = {};
    if (str) {
        this.data = this.parse(str);
    }
}

nvl.prototype = {
    parse: function(str) {
        var result = {}, pieces;
        var items = str.split(",");
        for (var i = 0; i < items.length; i++) {
            pieces = items[i].split("=");
            result[pieces[0]] = pieces[1];
        }
        return(result);
    },
    get: function(key, defaultVal) {
        var val = this.data[key];
        if (val === undefined) {
            val = defaultVal;
        }
        return(val);
    },
    set: function(key, value) {
        this.data[key] = value;
    },
    serialize: function() {
        var arr = [];
        for (var i in this.data) {
            if (this.data.hasOwnProperty(i)) {
                arr.push(i + "=" + this.data[i]);
            }
        }
        return(arr.join(","));
    }
};

実例: http: //jsfiddle.net/jfriend00/3urJF/

于 2012-10-10T23:59:02.213 に答える
0

これはどう:

//add nvl as a method to String prototype
String.prototype.nvl = function(){

    //new prototype for the dictionary object that gets returned
    var proto = {

        //convert the object literal back into a nvl
        toNvl: function(){

            var str = [];
            for(var i in this){

                if( this.hasOwnProperty(i) ){
                    str.push(i+'='+this[i]);
                }

            }

            //return str.join(',');
            return str.join(',');
        }
    },
    //set the prototype of the object literal to our own
    dict = Object.create(proto);

    //convert the string into an object literal
    keys = this.split(',');

    keys.forEach(function(val, index, arr){
        arr = val.split('=');
        dict[arr[0]] = arr[1];
    });

    return dict;
}


var pop = 'color=blue,num=234'.nvl(); //convert the string to an object

pop.color = 'red'; //access object properties normally.

pop = pop.toNvl(); //convert back to nvl. reassignment is unfortunately necessary
于 2012-10-11T04:33:40.253 に答える