【问题标题】:Javascript hashJavascript 哈希
【发布时间】:2016-03-30 14:18:11
【问题描述】:

我有这个哈希:

{
 a: [1,2],
 b: [1,2,3]
}

我需要生成这样的字符串:

a=1&a=2&b=1&b=2&b=3

我该如何解决这个问题? 我正在看lodash,但我无法解决它。

谢谢。

【问题讨论】:

  • 你试过什么?你为什么看lodash?为什么不使用简单的循环?
  • 也许可以看看Convert javascript object to URL parameters 了解一些想法
  • 除非您知道足够多的用户支持您想要的功能,否则我仍然会推迟使用 ES6 解决方案。我会坚持提出的简单循环之一(包括我的答案)
  • 这不是所示问题的重复!像a=1&a=2 这样的字符串将覆盖 之前的a 变量。这不是原始海报所要求的。
  • 我同意@Martin:不是同一个问题,也没有提供合适的解决方案。因此,我已标记为重新打开...可能那里有一个副本,但建议的不是它

标签: javascript


【解决方案1】:

使用 javascript Object.keys()map()join()ES6 arrow function

var arr = {
  a: [1, 2],
  b: [1, 2, 3]
};
var res = Object.keys(arr).map(v => arr[v].map(v1 => v + '=' + v1).join('&')).join('&');
document.write(res);

或不带箭头功能

var arr = {
  a: [1, 2],
  b: [1, 2, 3]
};

var res = 
    // get object keys
    Object.keys(arr)
// iterate over object keys and iterate
.map(function(v) {
  // iterate over inner array
  return arr[v].map(function(v1) {
    // generate prefered string and return 
    return v + '=' + v1
    // cconcatenate string array
  }).join('&')
  // concatenate string array
}).join('&');

document.write(res);

【讨论】:

  • 或者,只是为了好玩,如果输入不包含任何逗号,而不是两个 joinsObject.keys(arr).map(v => arr[v].map(v1 => v + '=' + v1)).join().replace(/,/g, '&') :)
【解决方案2】:

对于一个不错的 ES5 解决方案:

function hashToString(hash) {

    var str = '';
    for ( prop in hash ) {
        if ( !hash.hasOwnProperty(prop) ) continue;
        for (var i = 0; i < hash[prop].length; i++) {
            str += prop + '=' + hash[prop][i] + '&';
        };
    }
    str = str.slice(0, str.length-1);
    return str;

}

试试看!

有效:


好的!那么发生了什么?

首先,您要遍历第一级的每个项目。

您可以使用for ... in loop 执行此操作。您应该检查hasOwnProperty,以免遇到意外的原型属性。

然后,在第一个循环中,您要遍历 current 项中的项:

我们将使用常规的for loop 来实现这一点,因为这些项目只是数组。

在这里,我们要调整我们的字符串:

str += prop + '=' + hash[prop][i] + '&';

这会添加我们的属性名称(从for ... in 循环中保存为prop),然后是该属性数组中给定索引i 处的值。我们将留下一个尾随的&amp;,我们将在循环之外将其删除。

【讨论】:

  • 我认为您的答案略微夸大了,但它是 100% 正确且有用的。抓住一个 +1 :)。
  • 是的,有点啰嗦。但是当我开始时,我从像这样的长答案中学到了很多。他们不仅可以向您展示正确的代码,还可以向您展示编码时思考的方式。当我把它放在一起时,我喜欢展示我的思路是什么,因为这种思维方式通常会在未来的问题中有所帮助:)
【解决方案3】:

使用 for in 循环遍历哈希对象中的每个属性,然后从那里将每个值添加到字符串中,如下所示:

function hashToQueryString(hash) {
    var query = '';
    for (key in hash) {
        for (i=0; i<=key.length; i++) {
            query += key+'='+ myJSON[key]+'&';
        }
    }
    //remove the trailing &
    query = query.substr(0, query.length -1);
    return query;
}

(请记住,您还应该检查哈希中的每个属性是否包含一个有效的数组,并且您不会意外枚举任何您不想要的属性)

【讨论】:

  • 这正是我写的
【解决方案4】:

您可以为此使用qs。如果您碰巧超出整数,它还将处理所需的所有编码。

qs.stringify({
    a: [1,2],
    b: [1,2,3]
}, { indices: false });

【讨论】:

  • 这就是为什么有这么多库,这么简单的任务只有几行代码,为什么要一个新库来做:(
  • @musefan 这些库可以释放你的脑力,让你可以将其用于真正有创意的任务,而不是其他人已经妥善解决的任务。
  • @Li0liQ 这不是为一项任务引入图书馆的好理由。
  • 如果你需要库的其余部分,也许……如果你需要这个小东西,那么编写自己的代码比查找、安装和学习库更快
  • @Martin 够公平的。但是,您是否注意到在建议的 7 个答案中,只有两个考虑了 url 编码?依赖一个经过彻底测试的库不是一个足够好的理由吗?如果担心代码量,只需使用rollup
【解决方案5】:

我确信有一种更简洁的方法,但这里有一些 reduce 和 map 选项。

var obj = {
 a: [1,2],
 b: [1,2,3]
};

var params = Object.keys(obj).reduce( function (arr, key){
    arr.push(key + "=" + obj[key].join("&" + key + "="))
    return arr; 
}, []).join("&");

或者是否需要对查询字符串的值进行编码

var params = Object.keys(obj).reduce( function (arr, key){
    var mapped = obj[key].map( function (val) { return key + "=" + encodeURIComponent(val); }).join("&");
    arr.push(mapped)
    return arr; 
}, []).join("&");

【讨论】:

    【解决方案6】:

    let hash = {
      a: [1, 2],
      b: [1, 2, 3]
    };
    let str = '';
    for (let key in hash) {
      for (let value of hash[key]) {
        str += `${key}=${value}&`;
      }
    }
    alert(str.slice(0, -1));

    【讨论】:

      【解决方案7】:

      如果你不得不继续使用糟糕的旧 ES5,并且不想使用另一个库来完成简单的任务

      var myHash = {
         a: [1,2],
         b: [1,2,3]
      }
      var myString = '';
      Object.keys(myHash).map(function(key, index) {
        myHash[key].map(function(value) {
          myString += (myString ? '&' : '') + key + '=' + value;
        });
      });
      

      jsfiddle

      【讨论】:

        猜你喜欢
        • 2014-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-04
        • 2013-09-19
        • 2011-07-22
        • 2012-11-11
        • 2010-10-02
        相关资源
        最近更新 更多