【问题标题】:Convert Array-String to Object with Javascript or jQuery使用 Javascript 或 jQuery 将数组字符串转换为对象
【发布时间】:2012-06-20 13:12:52
【问题描述】:

我在页面上列出了每个 DOM 元素的 id

 var listy = $("*[id]").map(function(){
    return this.id;
 }).get().join(',');

因此,listy 的示例输出将是:

"home,links,stuff,things"

现在我想将列表 Array 转换为 Object,例如:

function toObject(arr) {
    var rv = {};
    for (var i = 0; i < arr.length; ++i)
        if (arr[i] !== undefined) rv[i] = arr[i];
    return rv;
}

但这会将所有内容放在Object 中,例如:

0: "h", 1: "o", 2: "m", etc...

我显然想要的是:

0: "home", 1: "links, 2: "stuff", etc..

我哪里出错了,我从Convert Array to Object得到了toObject()

这让我想到了一个类似但不同的问题:

Indexing page elements to JSON object? Or jQuery selector it every time?

【问题讨论】:

  • 你能把这个问题分成两个问题吗?如果一个“问题”实际上是多个不相关的问题,StackOverflow 就不能正常工作。

标签: javascript jquery object


【解决方案1】:

您的listy 是一个字符串,而不是一个数组。将您的第一个代码块更改为:

 listy = $("*[id]").map(function(){
    return this.id;
 }).get();

http://jsfiddle.net/P7YvU/

至于创建索引整个文档的对象:目的是什么?当您可以直接解析 DOM 时,自己执行此操作几乎没有什么优势——尤其是因为 jQuery 使它变得如此简单。您已经可以调用$('document &gt; body &gt; div &gt; h1').attr('id') 并获得相同的结果,而不是调用DOMJSONTHING.body.div.h1 来获取值“home”。

【讨论】:

  • 我只想拥有一个对象中的所有元素,我想用 .watch 监视该对象,当对象发生变化时,修改 DOM...
  • 而且,我不想每次都调用 jQuery 选择器,以节省资源。因为我想缓存 DOM 结构,所以我可以读/写它。
  • 在搜索 DOM 时 jQuery 所消耗的开销量可能比您最初构建对象所消耗的开销量要少。这些天计算机速度很快。您的对象还假设每个元素都有一个唯一的 ID,但情况可能并非如此。这是一个过早优化的例子,在你有理由认为你需要之前就试图节省周期。
  • 事情是......我想让这个对象检查一个ID是否已经存在,然后重命名它,然后再创建一个元素......
  • 所以按需做,而不是提前做。再说一遍:没有理由不这样做。
【解决方案2】:

这可能是获取对象的最短代码:

// your existing code (a tiny bit changed)
var idArray = $("*[id]").map(function() {
    return this.id;
}).get();

// this one liner does the trick
var obj = $.extend({}, idArray);

解决问题的更好方法 - 关联数组

但正如我在您的 cmets 中的其他答案中所读到的那样,这个对象结构在您的情况下可能不是最好的。你想要的是检查一个特定的 ID 是否已经存在。这个对象

{
    0: "ID1",
    1: "otherID",
    ...
}

不会有太大帮助。一个更好的对象是你的关联数组对象:

{
    ID1: true,
    otherID: true,
    ...
}

因为通过在if 语句中使用此条件进行检查,可以很容易地确定特定 ID:

if (existingIDs[searchedID]) ...

所有不存在的 ID 都将不符合此条件,所有存在的 ID 都将返回 true。但是要将您的 ID 数组转换为该对象,您应该使用以下代码:

// your existing code (a tiny bit changed)
var idArray = $("*[id]").map(function() {
    return this.id;
}).get();

// convert to associative "array"
var existingIDs = {};
$.each(idArray, function() { existingIDs[this] = true; });

或者根据需要的结果,您可以进一步优化:

var existingIDs = {};
$("*[id]").each(function() { existingIDs[this.id] = true; });

这将最大限度地加快您现有的 ID 搜索速度。只要您可以在 O(1) 中获取有关 ID 存在的信息,检查 ID 唯一性可能不需要分层对象结构。上层关联数组对象将为您提供这种超快速的可能性。当您使用新 ID 创建一个新对象时,您可以轻松地将其添加到现有的关联数组对象中,只需执行以下操作:

existingIDs[newID] = true;

就是这样。新 ID 将与其他 ID 一起缓存在同一个关联数组对象中。

注意:我可以看到您的代码隐含了全局(listy 变量)。小心并尽可能避免。

性能测试

作为@Blazemonger suggests 这不成立,我会说这种说法可能是真的。这一切都归结为:

  • 您拥有的具有 ID 的元素数量
  • 您想要进行的搜索次数

如果第一个通常像在常规 HTML 页面中一样低,其中 CSS 类比 ID 更频繁地使用,如果第二个足够大,那么 this performance test 证明关联数组可以比单独使用 jQuery 快一点.此测试中使用的 HTML 是 Stackoverflow 在移动网站上的问题列表的副本(因此我从源代码中删除脚本的工作较少)。我特意举了一个真实世界网站内容的例子,而不是准备好的测试用例,可以故意制造它以支持一种或另一种解决方案。

如果您搜索的规模要小得多,那么直接使用 jQuery 会比我更快,因为它不需要启动关联数组准备并立即开始搜索。

【讨论】:

    【解决方案3】:
    var str = 'home,links,stuff,things',
        obj = {};
    
    $.each(str.split(','), function(index, val) {
        obj[index] = val;
    });
    

    DEMO

    【讨论】:

    • 如果我想将Object的0、1、2索引更改为与element.tagName对应,那么,将'this'分配给对象索引。另外,如何防止它创建重复的对象索引,但将每个元素分组在一个标签节点下?
    • @TrySpace 对象不允许重复键。如果您尝试这样做,则最后一个值将保留。假设var x = {a: 'abc'},然后如果你尝试x.a = 'def',那么结果将是x= {a: 'def'};
    【解决方案4】:

    看看这个http://jsfiddle.net/ryan_s/XRV2m/

    会的

    1. 创建一个缓存来存储现有元素的 ID,这样您就不会在每次要生成新 ID 时都产生性能开销。
    2. 根据您传递给的标签名称自动生成增量 ID 它。
    3. 如果您真的打算使用 id,请更新缓存。

    为了方便,我只是在控制台上打印 id。

    根据您之前对其他人的一些回复,仅我的 2 美分。

    【讨论】:

      【解决方案5】:

      我的代码:

      jQuery.ajax({
              type: 'POST',                    
              url:'../pages/HomePage.php',            
              data:{param  : val},
              dataType:'HTML',                
              success: function(data)
              {
                  var data = data ;
                  obj = {};
      
      
      
                   $.each(data.split(','), function(k, v) {
                       obj[k]= v;
                  alert("success"); 
      
               $("#process_des").val(obj[0]);
                   });
      
              }
          }); 
      

      我的输出

      Array
      (
          [0] => FILLET SKIN OFF
          [1] => SF
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-19
        • 1970-01-01
        • 2018-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-28
        相关资源
        最近更新 更多