Преобразование javascript-объекта или массива в json для данных ajax

Итак, я создаю массив с информацией о элементе. Я просматриваю все элементы и сохраняю индекс. По какой-то причине я не могу преобразовать этот массив в объект json!

Это мой цикл массива:

var display = Array();
$('.thread_child').each(function(index, value){
   display[index]="none";
   if($(this).is(":visible")){
      display[index]="block";
   }
});

Я пытаюсь превратить его в объект JSON:

data = JSON.stringify(display);

Кажется, он не отправляет правильный формат JSON!

Если я передам код так, как это, он работает и отправляет информацию:

data = {"0":"none","1":"block","2":"none","3":"block","4":"block","5":"block","6":"block","7":"block","8":"block","9":"block","10":"block","11":"block","12":"block","13":"block","14":"block","15":"block","16":"block","17":"block","18":"block","19":"block"};

Когда я делаю предупреждение в объекте JSON.stringify, он выглядит так же, как и ручной кодированный. Но это не сработает.

Я схожу с ума, пытаясь решить это! Что мне здесь не хватает? Какой лучший способ отправить эту информацию для получения формата ручной кодировки?

Я использую этот метод ajax для отправки данных:

$.ajax({
        dataType: "json",
        data:data,
        url: "myfile.php",
        cache: false,
        method: 'GET',
        success: function(rsp) {
            alert(JSON.stringify(rsp));
        var Content = rsp;
        var Template = render('tsk_lst');
        var HTML = Template({ Content : Content });
        $( "#task_lists" ).html( HTML );
        }
    });

Использование метода GET, потому что я показываю информацию (не обновляя или не вставляя). Передача информации только в мой php файл.


КОНЕЦ РЕШЕНИЯ


var display = {};
$('.thread_child').each(function(index, value){
   display[index]="none";
   if($(this).is(":visible")){
      display[index]="block";
   }
});

$.ajax({
        dataType: "json",
        data: display,
        url: "myfile.php",
        cache: false,
        method: 'GET',
        success: function(rsp) {
            alert(JSON.stringify(rsp));
        var Content = rsp;
        var Template = render('tsk_lst');
        var HTML = Template({ Content : Content });
        $( "#task_lists" ).html( HTML );
        }
    });

Ответ 1

Я не совсем уверен, но я думаю, что вы, вероятно, удивлены тем, как массивы сериализуются в JSON. Пусть изолирует проблему. Рассмотрим следующий код:

var display = Array();
display[0] = "none";
display[1] = "block";
display[2] = "none";

console.log( JSON.stringify(display) );

Это напечатает:

["none","block","none"]

Вот как JSON фактически сериализует массив. Однако то, что вы хотите увидеть, это что-то вроде:

{"0":"none","1":"block","2":"none"}

Чтобы получить этот формат, вы хотите сериализовать объект, а не массив. Поэтому перепишите выше код следующим образом:

var display2 = {};
display2["0"] = "none";
display2["1"] = "block";
display2["2"] = "none";

console.log( JSON.stringify(display2) );

Это будет печатать в нужном формате.

Вы можете играть с этим здесь: http://jsbin.com/oDuhINAG/1/edit?js,console

Ответ 2

Вы можете использовать JSON.stringify(object) с объектом, и я просто написал функцию, которая будет рекурсивно преобразовывать массив в объект, как этот JSON.stringify(convArrToObj(array)), который является следующим кодом (более подробную информацию можно найти на этот ответ):

// Convert array to object
var convArrToObj = function(array){
    var thisEleObj = new Object();
    if(typeof array == "object"){
        for(var i in array){
            var thisEle = convArrToObj(array[i]);
            thisEleObj[i] = thisEle;
        }
    }else {
        thisEleObj = array;
    }
    return thisEleObj;
}

Чтобы сделать его более универсальным, вы можете переопределить функцию JSON.stringify, и вам больше не придется беспокоиться об этом, чтобы сделать это, просто вставьте это вверху страницы:

// Modify JSON.stringify to allow recursive and single-level arrays
(function(){
    // Convert array to object
    var convArrToObj = function(array){
        var thisEleObj = new Object();
        if(typeof array == "object"){
            for(var i in array){
                var thisEle = convArrToObj(array[i]);
                thisEleObj[i] = thisEle;
            }
        }else {
            thisEleObj = array;
        }
        return thisEleObj;
    };
    var oldJSONStringify = JSON.stringify;
    JSON.stringify = function(input){
        return oldJSONStringify(convArrToObj(input));
    };
})();

И теперь JSON.stringify примет arrays или objects! (ссылка на jsFiddle с примером)


Edit:

Здесь другая версия, которая немного эффективнее, хотя она может быть или не быть менее надежной (не уверен - это зависит от того, всегда ли JSON.stringify(array) возвращает [], что я не вижу много причин, почему это не будет, поэтому эта функция должна быть лучше, так как она немного меньше работает, когда вы используете JSON.stringify с object):

(function(){
    // Convert array to object
    var convArrToObj = function(array){
        var thisEleObj = new Object();
        if(typeof array == "object"){
            for(var i in array){
                var thisEle = convArrToObj(array[i]);
                thisEleObj[i] = thisEle;
            }
        }else {
            thisEleObj = array;
        }
        return thisEleObj;
    };
    var oldJSONStringify = JSON.stringify;
    JSON.stringify = function(input){
        if(oldJSONStringify(input) == '[]')
            return oldJSONStringify(convArrToObj(input));
        else
            return oldJSONStringify(input);
    };
})();

jsFiddle с примером здесь

js Тест производительности здесь, через jsPerf