Разбор \ повторение JSON `плохих` массивов в javascript с помощью jquery. Но разобрать такую ​​вещь? - PullRequest
2 голосов
/ 12 июля 2011

Я вернул JSON с моего сервера, как:

 {
    "user": {
        "nickname": "Ann",
        "width": 90,
        "height": 60
    },
    "user": {
        "nickname": "Dan",
        "width": 60,
        "height": 90
    }
}

Мне нужно перебрать всех пользователей и, например, предупредить псевдонимы, чтобы я попробовал следующий код:

var obj = jQuery.parseJSON('{    "user": {        "nickname": "ole",        "width": 333,        "height": 222    },    "user": {        "nickname": "jak",        "width": 333,   "height": 222 }}');
for (user in obj ) {
   alert( obj[user][nickname]);
}

Что не получается. Что мне делать, чтобы предупредить все имена пользователей (я не могу изменить способ, которым сервер возвращает json = (поэтому я надеюсь найти решение на стороне JS.)

Код умирает живым здесь.

Ответы [ 5 ]

3 голосов
/ 12 июля 2011

Проблема в том, что у вас есть массив внутри и массив. Вам нужно использовать что-то вроде

var obj = jQuery.parseJSON('[ {"user": {        "nickname": "ole",        "width": 333,        "height": 222    }},    {"user": {        "nickname": "jak",        "width": 333,   "height": 222 }}]');
for (i=0;i<obj.length;i++) {
     alert(obj[i].user.nickname);
}

Каждый «пользователь» является частью массива, т.е. 0,1 ...

Кроме того, как указали другие. Вы должны поместить имена в кавычки.

Наконец, JSON был не прав. Как видите, он должен был содержать скобки массива. Этот код работает. Вы можете сослаться на правильно сформированный JSON на www.json.org . В конечном счете, сервер должен будет предоставить вам действительный JSON, если вы хотите перебирать пользователей.

1 голос
/ 12 июля 2011

Честно говоря, если вы хотите сделать это надежно, вы можете изменить существующий чистый JS-анализатор JSON.Например, взгляните на простой синтаксический анализатор рекурсивного спуска Дагласа Крокфорда "parse_json": https://github.com/douglascrockford/JSON-js/blob/master/json_parse.js

В строке 272 (в функции объекта) у нас есть:

if (Object.hasOwnProperty.call(object, key)) {
    error('Duplicate key "' + key + '"');
}
object[key] = value();

Мы могли бы заменить это на:

if (Object.hasOwnProperty.call(object, key)) {
     if (Object.hasOwnProperty.call(dupKeys, key) && dupKeys[key]) {
         object[key].push(value());
     } else {
         object[key] = [ object[key], value() ];
         dupKeys[key] = true;
     }
} else {
     object[key] = value();
}

Конечно, около строка 259 мы должны были бы добавить переменную dupKeys,

var key,
    object = {},
    dupKeys = {};

Итогда json_parse проанализирует ваш JS.

var obj = json_parse("... your bad JSON here ...");
obj.user.forEach(function(user) {
    alert(user["nickname"]);
});
1 голос
/ 12 июля 2011

Поскольку вы не можете изменить серверную часть JSON, вам нужно изменить его на стороне клиента, прежде чем анализировать его.

Учитывая упомянутое JSON, вы можете использовать эту функцию:

function fixData( d ) {
    d = d.replace(/,\s*\"user\"\:/, ",");
    d = d.replace(/\"user\"\:/, "\"users\":[");
    d = d.replace(/}\s*$/, "]}");
    return d;
}

И просто «исправьте» JSON перед запуском parseJSON через:

var obj = jQuery.parseJSON(fixData(/* JSON string */));

Поиграйте с моим решением

Если вы хотите выполнить цикл по каждомуuser и output "псевдоним":

jQuery.each(obj.users, function(){ alert(this.nickname); });

Обратите внимание: Очевидно, что регулярное выражение в функции fixData хрупкое и не должно использоваться в качестве общего решения для любых другихисточники данных;вам нужно будет переписать его под конкретный вариант использования, если он не совпадает точно.

1 голос
/ 12 июля 2011

Есть две проблемы.

Во-первых, ключи должны быть уникальными. Вы дважды используете клавишу user в одной и той же записи объекта. Вам лучше использовать обозначение массива.

Во-вторых, [nickname] должно быть .nickname или ["nickname"].

var json = '{    "user": {        "nickname": "ole",        "width": 333,        "height": 222    },    "user": {        "nickname": "jak",        "width": 333,   "height": 222 }}';

   // make it an Array
json = '[' + json.slice(1,-1).replace(/"user":/g,'') + ']';

var obj = $.parseJSON( json );

for (var i = 0, len = obj.length; i < len; i++ ) {
   alert( obj[i].nickname);
}

Пример: http://jsfiddle.net/z7YxR/

1 голос
/ 12 июля 2011

Измените псевдоним на «псевдоним», поскольку для него не определена переменная:

alert( obj[user]["nickname"]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...