如何使用Underscore.js转换/混淆对象中的每个值

时间:2013-06-25 16:25:04

标签: javascript underscore.js

我正在尝试使用Underscore.js逐步浏览一个对象并对每个值进行转换/混淆,以便:

{
  "weather": "Cloudy",
  "degrees": 90
}

变为:

{
  "weather": "Claido",
  "degrees": 21
}

完全无法理解的原因 - 我试图混淆JSON对象而不破坏它们的结构。所以如果它是字符串,我用另一个随机元音替换任何元音。如果它是一个数字,我只需选择另一个随机数字,随机设置布尔值,依此类推。我可以构建每个元素类型操作,我现在确定如何递归地执行它。

我可以这样做:

var t = { "weather":"Cloudy", "degrees": 12, "snowing": false };
var newObj = {};
var g = _.each(t, function(value, key, list) {
  if (_.isString(value)){
     newObj[key] = value.replace(/[aeiou]/gi, '');
  }
  if (_.isNumber(value)){
     var n = Math.floor((Math.random()*10)+1);
     newObj[key] = n + value;
  }
  if (_.isBoolean(value)){
    newObj[key] = Math.random() >= 0.5;
  }
});
console.log(newObj);

一切都很好。问题在于数组和嵌套对象如下:

{
 "weather": "Cloudy",
 "outsideWeather": {
     "forecast": "Stormy",
     "outside": 48
 },
 "degrees": 12,
 "snowing": false
}

我的简单Switch案件在那时就崩溃了。任何想法如何递归地逐步遍历每个值,转换它,然后将对象构建回原始结构?

非常感谢

3 个答案:

答案 0 :(得分:2)

function recurse(mem, val, key) {
  if (_.isObject(val)) {
    mem[key] = _.reduce(val, recurse, {});
  } else {
    mem[key] = obfuscate(val);
  }
  return mem;
}

function obfuscate(value) {
  return "bananas!"; // your obfuscate logic
}

var yourObject = {
  foo: "bar",
  baz: { bizz: "buzz", ok: true }
}

var o = _.reduce(yourObject, recurse, {});
console.log(o);

http://jsfiddle.net/uEwJY/

答案 1 :(得分:2)

我已将scramble函数添加到mixin下划线:http://jsfiddle.net/ejWCD/2/

var target = {
 "weather": "Cloudy",
 "outsideWeather": {
     "forecast": "Stormy",
     "outside": 48
 },
 "degrees": 12,
 "snowing": false
};

_.mixin({
    scramble: function(obj) {
        var newobj = {};
        _(obj).each(function(el, key) {
            switch( typeof el ) {
                case 'object':
                    newobj[key] = _(el).scramble();
                    break;
                case 'boolean':
                    newobj[key] = !el;
                    break;
                case 'string':
                    newobj[key] = el.replace(/[aeiou]/gi, 'aeiou'.charAt(_.random(4)));
                    break;
                case 'number':
                    newobj[key] = _.random(el*10);
                    break;
            }
        });
        return newobj;
    }
});

console.log( _(target).scramble() );

答案 2 :(得分:1)

我会这样做:

var obfuscate = function(object) {
    if(_.isNumber(object)) {
        return object + 1;
    } else if(_.isString(object)) {
        return object.replace(/[aeiou]/gi, '');
    } else if(_.isBoolean(object)) {
        return Math.random() >= 5;
    } else if(_.isArray(object)) {
        return _.map(object, obfuscate);
    } else if(_.isObject(object)) {
        return _.object(_.map(object, function(value, key) {
            return [key, obfuscate(value)];
        }));
    }
}

注意:我并没有混淆key。如果要这样做,可以轻松更改一行代码。此外,如果对象是一个数组,我会混淆每个元素。

测试:

var input = {
 "weather": "Cloudy",
 "outsideWeather": {
     "forecast": "Stormy",
     "outside": 48
 },
 "degrees": 12,
 "snowing": false
};

console.log(obfuscate(input));

http://jsfiddle.net/Dogbert/K2EML/