你如何通过Index ASC阻止Chrome和Opera对JSON对象进行排序?

时间:2011-02-16 18:44:27

标签: jquery json google-chrome opera

我遇到了问题。

使用ajax我使用:

发送了一个正确形成的JSON对象
            $.ajax({
                type: "POST", 
                url: SITE_URL+'/data.php',
                dataType: "json",
                data: { ajax: 1 },
                success: function(data) {
                    console.log(data);
                }
            });

然而,Opera和Chrome虽然收到相同的对象,但是按不正确的顺序打印出对象,看起来它们都是按ID号排序而不是单独排序!

有没有办法停止此自动排序?

编辑,在发现它是按索引号排序之后,我认为最好的方法可能是不使用索引来存储object_id,而是存储我想要按顺序排序对象的id号。

但是我仍然想知道是否有办法停止排序。

谢谢

Edit2,我只想指出,我将采用不同的方式来做这件事,因为我觉得我用这种方法滥用对象。但是我仍然想了解为什么Opera和Chrome认为他们有权更改我的对象ID的顺序:

问题在于我试图节省处理能力,假设我们有人有ID,

1.John,2.Frank和3.Sally。然而,这些人中的每一个都具有高度属性集(和其他东西)。 1.约翰.180,2.Frank.220,3.Sally.150。为了节省处理费用,我要求人们根据他们的身高对结果进行排序,这样我就得到了一个包含其他属性的2,1,3的数组。我JSON这个数组并将其发送到浏览器。

现在FF将保留新订单 人们[1]仍然是约翰,但在一个人的循环中,他们将会失灵。

如果我无法解决这个问题,我将不得不在SQL阶段进行排序,并在JS阶段添加额外的循环和排序到数组中,尽管我希望避免对浏览器施加更多压力Js重页。

非常感谢

17 个答案:

答案 0 :(得分:23)

有同样的问题,遵循dmc的解决方案,但只是在int值前添加了一个空格,使其成为一个字符串。

使用空格而不是另一个非数字字符的优点是随后的POSTed值可以直接在mySQL搜索子句中使用,而不必再次删除它。

答案 1 :(得分:19)

不同的浏览器以不同的方式处理对象,我的错是尝试使用我构建对象的顺序作为参考,我不应该这样做。

答案 2 :(得分:18)

将整数更改为字符串对我来说不起作用(Chrome,jQuery 1.7.1)。 所以为了保持秩序(是的,它的对象滥用),我改变了这个:

optionValues0 = {"4321": "option 1", "1234": "option 2"};

到这个

optionValues0 = {"1": {id: "4321", value: "option 1"}, "2": {id: "1234", value: "option 2"}};

答案 3 :(得分:14)

除非JSON是一个数组,而不是一个对象,否则没有标准表明它必须按某种顺序排列。但是,这不应该是一个问题,因为您不需要遍历对象来获取数据,您可以简单地引用该属性。

答案 4 :(得分:6)

有些浏览器会对int进行排序,另一方面很容易将其更改为字符串并稍后恢复,我的解决方案是将“i”添加到密钥,这就成了一个技巧。适用于每个浏览器:)希望有帮助:)

答案 5 :(得分:5)

我有同样的“问题”,并且不想回去并在代码中做太多改变。弄清楚至少Google Chrome只会重新排序数字索引。只要索引被视为字符串,它就会以“预期”顺序显示。有人可以在Opera上验证这个吗?

答案 6 :(得分:2)

这些解决方案都不适合我(2017年8月)。即使我使用了字符串Chrome和Safari(没有测试其他浏览器)仍然根据字符串进行排序。我所做的是将整数键与值字符串连接起来。 e.g

result[string_value + str(integer_key)] = string_value

这样首先是字符串,浏览器可以自由排序。然后我用一些简单的逻辑将键与值分开。

希望这有帮助。

答案 7 :(得分:1)

似乎最好的方法是完全避免关联数组。当你想发送一个关联数组时,只需将它作为两个独立的数组发送 - 一个键和一个值。这是执行此操作的PHP代码:

    $arWrapper = array();
    $arWrapper['k'] = array_keys($arChoices);
    $arWrapper['v'] = array_values($arChoices);
    $json = json_encode($arWrapper);

和简单的JavaScript代码,可以用它做任何你喜欢的事情

            for (i=0; i < data['k'].length; i++) {
                console.log('key:' + data['k'][i] + ' val:' + data['v'][i]);
            }

我遇到了类似的问题并发布在jQuery: $.getJSON sorting the data on Chrome / IE?

答案 8 :(得分:1)

你需要欺骗谷歌Chrome(和其他人)认为你有一个字符串而不是一个数字。 将JSON更改为{"2423":'abc', "2555":'xyz'}将无效。

我不得不使用&#34; _2423&#34;和&#34; _2555&#34;作为我的对象中的索引,让它工作。

此外,调试输出到console.log或使用for x in y给出了与_.each方法不同的结果(参见下划线框架)。

您可以在JSFiddle中看到我的测试/校对,其中"_"与无前缀和for x in y循环:http://jsfiddle.net/3f9jugtg/1/

答案 9 :(得分:1)

我使用以下代码解决了这个问题:

$('.edit_district').editable("/moderator/sale/edit_sale/", {
    data   : " {'_7':'10 street', '_9':'9 street', '_11':'park'}",
    type   : 'select',
    submit    : 'OK',
    onblur : 'submit'
});

并在script.php中:

...
case "id_district":

$district = Districts::GetDistrictByID(Database::getInstance(), (int)substr($value,1));

if($district instanceof District){
    $data["id_district"] = $district->id_district;
    echo $district->title;
}

break;

...

答案 10 :(得分:0)

当我添加另一个区域并需要按特定方式对它进行排序时,我遇到了同样的问题。我在数据库表中添加了一个“排序”字段,然后按我的期望对select进行了排序,原始JSON符合预期,但是我通过AJAX将数据填充到其中的select字段仍按键(region_id)对其进行了排序?我的问题是region_id是一个整数,我通过封装键使其改为字符串来解决它:

  while($row = $result->fetch_array()) {
    $this->regions["'".$row['region_id']."'"] = $row['region'];
  }

旧代码为:

  while($row = $result->fetch_array()) {
    $this->regions[$row['region_id']] = $row['region'];
  }

比在键的另一端添加各种字符要优雅得多。

我希望这可以帮助其他人获得更简洁的代码:-)

答案 11 :(得分:0)

可以提供帮助的一个技巧如下:

在for循环中准备数据时,必须在键中添加“i”,这就成了一个技巧。适用于每个浏览器。

例如:

 for(var i=1;i<4;i++){

 data[''+i+''+your_random_generatedId+'']  = {"questionText":"","answer":"","options":"",noOfOptions:""};

 console.log(data[''+i+''+your_random_generatedId+'']); // This prints the log of each object inside data 

 }

 console.log(data); // This will print the Object without sorting

因此,您的对象将如下:

Object {156674: Object, 201705: Object, 329709: Object}

希望这有助于:)

答案 12 :(得分:0)

我对chrome有同样的问题,令人沮丧。我以某种方式发送它,为什么不能让我认真对待它呢?我知道没有“标准”方式,但如果是这样的话,为什么要强加自己的订单?

无论如何,我通过将对象转换为数组来处理它,以便

{ 0: "", 2: "Frame", 1: "Masonry" }

成了

[[ 0, "" ], [ 2, "Frame" ], [ 1, "Masonry" ]]

不得不改变一些javascript,但它最终完美运行。

答案 13 :(得分:0)

我遇到了同样的问题,并花了一些时间来研究甚至导致它的问题,这真是一种痛苦。我最终从索引中删除了ID并使用了array_push,而不是:

$section[$s_id]['Type'] = $booktype;

等。我把它改成了

array_push($sections, array('ID'=>$s_id, 
                            'CourseID'=>$courseid, 
                            'SectionName'=>$secname, 
                            'Order'=>$order, 
                            'Created'=>$created, 
                            'Description'=>$desc
                            ));

这允许我保留PHP的排序,因为新的索引已经按顺序排列(0,1,2,3等,而不是112,56,411等)

答案 14 :(得分:0)

在某些情况下,您需要使用记录ID在后期处理循环中对事物进行分组。在密钥值周围加上引号将起作用。或者您可以在最终数组上使用array_merge来重置密钥。

$processed_array = array(
  235=>array("id"=>235,"name"=>"Something"),
  27=>array("id"=>27,"name"=>"Something")
);

array_merge($processed_array);

print_r($ processed_array);现在返回以下内容:

$processed_array = array(
  0=>array("id"=>235,"name"=>"Something"),
  1=>array("id"=>27,"name"=>"Something")
);

答案 15 :(得分:0)

在JSON字符串参数中创建对象标识符,它无需自动排序。

答案 16 :(得分:-1)

当您将数据对象传递给console.log时,JavaScript将最终调用数据对象的toString()方法。由于您不喜欢数据的toString()方法的默认格式,因此您必须自己完成这项工作。

如果你想要那种类型的控件,你可以自己转储对象的字段 - 你必须得到键/字段并对它们进行排序然后自己构建字符串版本。

类似的东西:

for (field in obj)
    add field to array

sort array into whatever order you want

for (field in array)
    get value of field from obj
    create string of field : value, append to main string

console.log(main string)