JavaScript,简化对象转换

3

我有一个函数,它可以将一个对象转换为(略有不同的)另一个对象。我先写了一个初版,只是为了让它能够工作,现在我想简化这个函数,感觉可以删减一些代码,但需要一些帮助。

所以对象是这样传入的

 {"module1":{"calender":["yes","no","maybe"]}}

并且像这样被吐出来。
 {module1: "calender,yes,no,maybe"}

所以,这是我现在拥有的内容:
 function(obj) {

                for (i in obj) {

                    for (p in obj[i]) {
                        var decodeModule = encodeURIComponent(decodeURIComponent(i));
                        var newObj = {};
                        var frontOf = encodeURIComponent(p);
                        var backOf = ""
                            //needs work
                        var lastItem = obj[i][p][obj[i][p].length - 1];
                        for (y in obj[i][p]) {

                            if (obj[i][p][y] == lastItem) {
                                //replace "," in last item
                                backOf += encodeURIComponent(decodeURIComponent(obj[i][p][y]));
                            } else {
                                backOf += encodeURIComponent(decodeURIComponent(obj[i][p][y])) + ",";
                            }
                        };
                        newObj[decodeModule] = frontOf + "," + backOf;
                    }
                }
                return newObj;
            }

我已经知道第二个循环(for (p in obj [i]))不需要循环,因为该级别始终只有1个项目。 除此之外,我有点困惑如何清理这个代码块 - 有人建议我可能要使用.reduce或.map来使用更少的代码? 我还在我的代码中使用了underscore,如果可以的话,这里会有所帮助。 如果有人能帮我使这个代码变得更加优美,那就太好了。 谢谢阅读!

2个回答

2

好的,这是一个有趣的练习。完成后,我想:“我们为什么要做这个?” :)

我将属性值减少到字符串,然后使用正则表达式和 _.map 进行替换以替换每个匹配项。 http://codepen.io/anon/pen/VYgodo

我知道这也可以改进。请有人拆开它!

var input = {
"module1": {
"calender": ["yes", "no", "maybe"]
},
"module2": {
"falender": ["yes", "no", "jein"]
}
};

//output: {module1: "calender,yes,no,maybe"}

function reduceObj(obj) {
newObj = {};


_.each(obj, function (value, key, list) {

var r = new RegExp(/(?:^({).*(:\[).*(\]})$)/);
//reduce property value to string and replace using regex
newObj[key] = JSON.stringify(list[key]).replace(r, function (match, p1, p2,    p3, p4, p5, offset, string) {
//this may be the only way to replace each capture
_.map([p1, p2, p3, p4], function (value, index, list) {
match = match.replace(value, "");
}); //end map

//replace double quote with comma and single quote with nothing
return match.replace(/\"\"/g, ',').replace(/\"/g, "");

}); //end replace


}); //end each

return newObj;
};

$(document).ready(function () {
console.log(reduceObj(input));
$('#output').html(JSON.stringify(reduceObj(input)));

});

在这个方法中有没有办法追踪encodeURIComponent(decodeURIComponent)部分? - user2815588
抱歉,让我澄清一下 - 那个键名和最终对象内部的项目需要通过encodeURIComponent(decodeURIComponent(这里的内容))进行处理,我不确定如何将其插入到您的方法中,我尝试了一会儿。(我正在从URL查询字符串中提取它们并将它们放回去,因此我需要解码/重新编码) - user2815588
我有点困惑。你能展示一下最终的URL是什么样子吗?你是想实现这个吗?:www.website.com/?calender=yes,no,maybe - mags

1
像这样的东西怎么样?没有下划线,没有正则表达式,只有好老式的原生JavaScript。

var input = {
  1: {
    "calender": ["yes", "no", "maybe"]
  },
  "module2": {
    "test2": ["|", "#", "&", "?", ",", "+", " ", "\\", "\""]
  },
  "One More for Good Measure": {}
};

function reduceObj(obj) {
  function helper(o) {
    var key = Object.keys(o)[0];
    if (typeof key != 'string') return '';
    return [].concat(key, o[key]).map(e_d).join(',');
  }

  function e_d(str) {
    return encodeURIComponent(decodeURIComponent(str));
  }
  
  var newObj = {}, prop;

  for (prop in obj) {
    if (obj.hasOwnProperty(prop)) {
      newObj[e_d(prop)] = helper(obj[prop]);
    }
  }
  return newObj;
}

var output = reduceObj(input);
document.write('<pre>' + JSON.stringify(output, 0, 2));

如果在module2下有多个键(例如),你只需要更改helperDEMO
function helper(o) {
  var arr = [];   
  Object.keys(o).forEach(function(key) {
      o[key].unshift(key);
      arr = arr.concat(o[key]);
  });
  return arr.map(e_d).join(',');
}

这也太棒了!感谢您的帮助。我可以把编码/解码部分放在这里吗? - user2815588
@Alex,我非常确定你可以做到,我会在答案中添加它。 - robbmj
@Alex,我不太确定你在使用编码/解码做什么,如果你能解释一下为什么要使用这些函数,那会对我很有帮助。 - robbmj
它们正在被编码,因为它们被放在URL字符串上。进行编码(解码项目)的原因是该项目可能已从URL字符串中提取(也可能没有),因此在进行编码之前首先对其进行解码,以避免重复编码。 - user2815588
所以它会对模块名称本身进行编码(解码),然后对其中的项目进行编码,最后将其推入最终的newObj中。 - user2815588
1
@Alex,好的,我已经在答案中添加了编码/解码内容,你可以在input.module2.test2中看到效果。 - robbmj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接