使用Javascript或jQuery将数组字符串转换为对象。

3
我将列出页面上每个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..

我错在哪里了,我从这里获得了toObject()方法:将数组转换为对象

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

将页面元素索引到JSON对象?还是每次使用jQuery选择器?


你能把这个问题分成两个吗?如果一个“问题”实际上是多个不相关的问题,那么StackOverflow的效果就不太好了。 - Dancrumb
5个回答

5

你的listy是一个字符串,而不是数组。请修改你的第一段代码为:

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

http://jsfiddle.net/P7YvU/

如果要创建一个索引整个文档的对象,那么目的是什么? 当您可以直接解析DOM时,自己这么做几乎没有优势 - 特别是jQuery已经使其变得如此容易。 您可以调用$('document > body > div > h1').attr('id')而不是调用DOMJSONTHING.body.div.h1来获取值“home”,并获得相同的结果。


我只想要一个对象中的所有元素,使用.watch监视该对象,当对象发生更改时,修改DOM... - TrySpace
当使用jQuery搜索DOM时,消耗的开销可能比您首次构建对象时消耗的开销要少。如今的计算机速度非常快。您的对象还假定每个元素都有唯一的ID,但这可能并不是事实。这是一种过早优化的情况,在您甚至没有理由认为需要节省周期之前尝试节省它们。 - Blazemonger
事实是..我想让这个对象检查一个ID是否已经存在,然后重命名它,在创建元素之前... - TrySpace
因此,按需执行该操作,而不是提前执行。再说一遍:没有理由不这样做。 - Blazemonger
你所说的“缓存页面上的每个对象”是什么意思?我们只谈论一个对象。一个ID的关联数组。没有其他对象。我还编辑了我的答案,包括性能测试数据和一些解释。问题在于我们都是正确的。这取决于情况... - Robert Koritnik
显示剩余5条评论

3
这可能是获取对象的最短代码:
// 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);

你的问题有更好的解决方案 - 关联数组

但是根据我在其他答案评论中读到的信息,这种对象结构可能并不适合您的情况。您想要的是检查特定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搜索速度。检查ID唯一性可能不需要分层对象结构,只要您可以在O(1)内获取有关ID存在的信息即可。上部联想数组对象将为您提供此超级快速的可能性。当您使用新ID创建新对象时,您只需执行以下操作即可将其轻松添加到现有的联想数组对象中:
existingIDs[newID] = true;

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

注意:我看到你的代码使用了隐式全局变量(listy变量)。请小心并尽可能避免使用。

性能测试

@Blazemonger建议,我认为这并不站得住脚。全部归结为以下两点:

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

如果第一个通常很低,例如在普通HTML页面中,CSS类比ID更频繁地使用,并且如果第二个足够大,则此性能测试证明关联数组可以比仅使用jQuery快得多。此测试中使用的HTML是Stackoverflow移动站点上问题列表的副本(因此我需要从源代码中消除脚本)。我故意选择了一个真实网站内容的例子,而不是制作有利于其中一种解决方案的测试用例。

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


2
var str = 'home,links,stuff,things',
    obj = {};

$.each(str.split(','), function(index, val) {
    obj[index] = val;
});

DEMO


如果我想要更改对象的0、1、2索引以对应于element.tagName,那么将'this'分配给对象索引。然后,如何防止创建重复的对象索引,而是将每个元素分组在一个标记节点下? - TrySpace
1
@TrySpace对象不允许重复的键。如果您尝试这样做,最后一个值将保留。假设var x = {a: 'abc'},然后如果您尝试x.a ='def',则结果将是x = {a:'def'}; - thecodeparadox

1

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

它将会:

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

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

这只是基于您对其他回复的一些评论而提出的我的两分钱建议。


1

我的代码:

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
)

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