如何将一个表示数组的字符串转换回数组?

3

我是一个有用的助手,可以翻译文本。

我正在尝试某件事...

比如我有这个:

<div id="helloworld" 
     call="chart" 
     width="350" height="200" 
     value="[[4, 8, 1, 88, 21],[45, 2, 67, 11, 9],[33, 4, 63, 4, 1]]" 
     label="['test1', 'test2', 'test3', 'test4', 'test5']"/>

我正在使用jQuery将所有元素的属性提取到一个对象数组中,这部分工作已经完成,我得到了如下结果:

Object { id="helloworld", call="chart" ... }

我需要完成的第二部分是将“数组的字符串表示”转换成一个实际的数组。使用JSON.parse()函数,对于我的值可以起作用,但是尝试对标签进行相同的操作时失败了,因为里面含有单引号(')。我尝试使用\"来转义,但仍然无法成功。
请问有没有一种优雅的方法将其转换回数组?

4
这些似乎是自定义属性,除非你正在使用[data-*]属性,否则不应定义自己的自定义属性。 - zzzzBov
这只是在您想要验证您的HTML时才需要。 - Alan
1
JSON.parse不认为'(单引号)是有效的字符串。你需要更改服务器端呈现标签的代码,使用双引号或者在尝试解析之前将所有'(单引号)替换为"(双引号)。 - Selvakumar Arumugam
1
手动创建数组真的不是问题 -> FIDDLE - adeneo
在结合 Vega 和 Adeneo 的解决方案后,发布了解决方案!请参见下文。 - codenamezero
显示剩余5条评论
5个回答

5
作为使用jQuery和自定义属性的用户,首先需要修复的是属性:
而不是:
<div id="helloworld" 
     call="chart" 
     width="350" height="200" 
     value="[[4, 8, 1, 88, 21],[45, 2, 67, 11, 9],[33, 4, 63, 4, 1]]" 
     label="['test1', 'test2', 'test3', 'test4', 'test5']" />

你应该使用:

<div id="helloworld" 
     data-call="chart" 
     width="350" height="200" 
     data-value="[[4, 8, 1, 88, 21],[45, 2, 67, 11, 9],[33, 4, 63, 4, 1]]" 
     data-label='["test1", "test2", "test3", "test4", "test5"]'></div>

请确保您的数据也使用有效的JSON编码。

这样做后,您可以使用jQuery的.data()方法访问属性的值。

$('#helloworld').data('label'); //returns the actual array

在某些情况下,您可能希望使用.attr()来访问属性的字符串表示形式。


如果你一定要保留数据原样,而且可以保证“字符串”不包含特殊字符,那么你可以调用$.parseJSON($('#helloworld').attr('data-label').replace("'", '"'));,但是如果字符串包含引号或其他没有正确编码/转义的特殊字符,则会失败。

这是目前为止最好的答案。在外部使用单引号比在内部转义双引号更容易。 - Matt Browne

1

由于您的 字符串 看起来像是JSON,因此您可以使用 JSON.parse 进行解析。但是 JSON 不允许使用 ',因此您无法解析该标签。

是否有可能更改生成HTML的方式?如果您使用正确的HTML编码生成它,就可以轻松地将其解析为JSON。

<div label="[&quot;test1&quot;, &quot;test2&quot;, &quot;test3&quot;, &quot;test4&quot;, &quot;test5&quot;]">

JSON.parse(elm.label); // should work

1
正如我在问题中提到的那样,它对于值是有效的,但对于标签则无效,因为其中有单引号。 :( - codenamezero

1
由于它不是有效的JSON格式,一个选项是:
arr = x.replace(/[\[\]']/g, '').replace(/\,\s/g, ',').split(',');

其中x"['test1', 'test2', 'test3', 'test4', 'test5']"

上述代码将给你一个数组:

["test1", "test2", "test3", "test4", "test5"]

1

0

好的,所以综合了我在网上找到的东西以及@Vega和@adeneo的答案,最终的解决方案如下:

使用以下jQuery方法允许我通过调用空白attr()获取所有内容:

(function($) {
    var _old = $.fn.attr;
    $.fn.attr = function() {
        if (this[0] && arguments.length === 0) {
            var map = {};
            var i = this[0].attributes.length;
            while (i--) {
                map[this[0].attributes[i].name.toLowerCase()] = this[0].attributes[i].value;
            }
            return map;
        } else {
            return _old.apply(this, arguments);
        }
    }
}(jQuery));

我可以这样获取所有属性:

var data = $(document.getElementById(id)).attr();

因此,我将保持元素属性与之前完全相同(包括HTML5的调整):

<div id="helloworld"
     data-call="chart"
     data-width="350"
     data-height="200"
     data-stacked="true"
     data-value="[[4, 8, 1, 88, 21],[45, 2, 67, 11, 9],[33, 4, 63, 4, 1]]" 
     data-label="['test1', 'test2', 'test3', 'test4', 'test5']"/>

我随后使用 JSON.parse() 来处理 data-value 数据,然后使用 @adeneo 的方法来处理字符串数组。
    data.value = JSON.parse(data.value);
    data.label = data.label.split(',').map(function(val) { return val.trim().replace(/(\'|\[|\])/g,''); });

为了我的其他js代码的目的,我只需从键中删除data-,现在一切都很好!!

for (key in data) {
    var newKey = key.replace("data-","");
    if (newKey != key) {
        data[newKey] = data[key];
        delete data[key];
    }
}

现在我可以将数据传递给我的现有函数了!!!:)

之前我如何调用我的函数:

var data = {
    id: 'helloworld',
    width: 350,
    height: 200,
    value: [
        [4, 8, 1, 88, 21],
        [45, 2, 67, 11, 9],
        [33, 4, 63, 4, 1]
    ],
    stacked: true,
    label: ["test1", "test2", "test3", "test4", "test5"]
};
chart(data);

现在我可以使用jQuery,找到所有具有特定类名的元素,然后只需解析属性以触发调用。 :)

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