通过索引获取JSON对象的属性?

52

假设有以下JSON对象:

var obj = {
    "set1": [1, 2, 3],
    "set2": [4, 5, 6, 7, 8],
    "set3": [9, 10, 11, 12]
};

可以使用以下代码获取"set2"属性:

obj["set2"]

有没有一种方法可以按索引检索"set2"属性?它是JSON对象的第二个属性。这样做当然是不起作用的:

obj[1]  

假设我想获取JSON对象的第二个属性,但我不知道它的名称 - 那么我该如何做呢?

更新:是的,我知道对象是无序属性的集合。但我认为浏览器不会改变JSON文本/字符串定义的“原始”顺序。


你需要通过遍历整个结构来找到包含元素。我认为没有其他方法。 - Pekka
7
如果我理解得正确,那么这里的每一个答案都是错误的。obj[Object.keys(obj)[1]] 返回索引为 1 的属性值:[4, 5, 6, 7, 8]。请注意,我的翻译尽可能保留了原文的意思和语气,同时使其更加通俗易懂,没有添加解释或其他额外内容。 - The Muffin Man
https://dev59.com/amHVa4cB1Zd3GeqPpbIZ#39303950 - M. Salah
相关帖子请点击此处 - RBT
12个回答

38

JavaScript中的对象是无序属性的集合。对象是哈希表。

如果您想让属性按字母顺序排序,一个可能的解决方案是为属性在一个单独的数组中创建索引。就在几个小时前,我回答了一个stackoverflow上的问题,您可以去看一下:

以下是适用于您的对象1的快速适配:

var obj = {
    "set1": [1, 2, 3],
    "set2": [4, 5, 6, 7, 8],
    "set3": [9, 10, 11, 12]
};

var index = [];

// build the index
for (var x in obj) {
   index.push(x);
}

// sort the index
index.sort(function (a, b) {    
   return a == b ? 0 : (a > b ? 1 : -1); 
}); 

然后,您将能够执行以下操作:

console.log(obj[index[1]]);

之前我引用的答案提供了一种可重复使用的解决方案,可以迭代这样的对象。除非您可以像@Jacob Relkin在其他答案中建议的那样更改JSON,这可能更容易。


1 你可能希望使用hasOwnProperty()方法来确保属性属于您的对象,而不是从Object.prototype继承的。


1
那是一个非常详细的答案 :) 不过,在for in循环内部,你不应该进行hasOwnProperty检查吗?(以防某些东西增强了Object.prototype对象。) - Šime Vidas
@Šime Vidas:是的,我不想让示例过于复杂……但是这是个好主意。我会在这个答案和那个答案中加上一条说明。 - Daniel Vassallo
3
obj[Object.keys(obj)[1]] 可以正常工作。Object.keys(obj)[0] 返回 "set1",然后你可以像平常一样将其放入属性访问器中。 - The Muffin Man

25

我知道这是一个旧问题,但我找到了一种按索引获取字段的方法。 您可以使用Object.keys方法实现此目的。

当您调用Object.keys方法时,它会按分配顺序返回键(请参见下面的示例)。我在以下浏览器中测试了下面的方法:

  • Google Chrome版本43.0
  • Firefox版本33.1
  • Internet Explorer版本11

我还编写了一个小扩展以扩展对象类,因此您可以使用getByIndex调用对象的第n个键。

// Function to get the nth key from the object
Object.prototype.getByIndex = function(index) {
  return this[Object.keys(this)[index]];
};

var obj1 = {
  "set1": [1, 2, 3],
  "set2": [4, 5, 6, 7, 8],
  "set3": [9, 10, 11, 12]
};

var obj2 = {
  "set2": [4, 5, 6, 7, 8],
  "set1": [1, 2, 3],
  "set3": [9, 10, 11, 12]
};

log('-- Obj1 --');
log(obj1);
log(Object.keys(obj1));
log(obj1.getByIndex(0));


log('-- Obj2 --');
log(obj2);
log(Object.keys(obj2));
log(obj2.getByIndex(0));


// Log function to make the snippet possible
function log(x) {
  var d = document.createElement("div");
  if (typeof x === "object") {
    x = JSON.stringify(x, null, 4);
  }
  d.textContent= x;
  document.body.appendChild(d);
}


2
Jeroen,太棒了。这正是我今晚所需要的。感谢您抽出时间回答这个老问题。 - Steve Gaines

20

不,JavaScript对象中没有办法按索引访问元素。

如果您可以访问此JSON的源代码,则一种解决方案是将每个元素更改为JSON对象,并将键放置在该对象内,如下所示:

var obj = [
    {"key":"set1", "data":[1, 2, 3]},
    {"key":"set2", "data":[4, 5, 6, 7, 8]},
    {"key":"set3", "data":[9, 10, 11, 12]}
];

然后您就可以通过数字方式访问元素:

for(var i = 0; i < obj.length; i++) {
    var k = obj[i]['key'];
    var data = obj[i]['data'];
    //do something with k or data...
}

16

简单的解决方案,只需要一行代码。

var obj = {
    "set1": [1, 2, 3],
    "set2": [4, 5, 6, 7, 8],
    "set3": [9, 10, 11, 12]
};

obj = Object.values(obj);

obj[1]....

11

在这里,您可以通过以下方式访问“set2”属性:

    var obj = {
        "set1": [1, 2, 3],
        "set2": [4, 5, 6, 7, 8],
        "set3": [9, 10, 11, 12]
    };

    var output = Object.keys(obj)[1];

Object.keys会将提供的对象的所有键以数组的形式返回。


5

Jeroen Vervaeke的答案是模块化的,工作得很好,但如果与依赖于JavaScript“对象作为哈希表”功能的jQuery或其他库一起使用,它可能会导致问题

我对其进行了一些修改,使其可与这些库一起使用。

function getByIndex(obj, index) {
  return obj[Object.keys(obj)[index]];
}

4
您可以遍历对象并将属性分配给索引,就像这样:
var lookup = [];
var i = 0;

for (var name in obj) {
    if (obj.hasOwnProperty(name)) {
        lookup[i] = obj[name];
        i++;
    }
}

lookup[2] ...

然而,正如其他人所说,原则上键是无序的。如果您有依赖顺序的代码,请视其为hack。确保您拥有单元测试,以便在它出现问题时进行发现。


1
var obj = {
    "set1": [
        1,
        2,
        3
    ],
    "set2": [
        4,
        5,
        6,
        7,
        8
    ],
    "set3": [
        9,
        10,
        11,
        12
    ]
};

var outputKeys = Object.keys(obj)[1];

var outputValues = Object.values(obj)[1];
//outputKeys would be "set2"`enter code here`
//outPutValues would be [4,5,6,7,8]

1
"""
This could be done in python as follows.
Form the command as a string and then execute
"""
context = {
    "whoami": "abc",
    "status": "0",
    "curStep": 2,
    "parentStepStatus": {
        "step1":[{"stepStatus": 0, "stepLog": "f1.log"}],
        "step2":[{"stepStatus": 0, "stepLog": "f2.log"}]
    }
}
def punc():
          i = 1
          while (i < 10):
              x = "print(" + "context" + "['parentStepStatus']" + "['%s']"%("step%s")%(i) + ")"
              exec(x)
              i+=1
punc()

0

这很简单...

var obj = {
    "set1": [1, 2, 3],
    "set2": [4, 5, 6, 7, 8],
    "set3": [9, 10, 11, 12]
};

jQuery.each(obj, function(i, val) {
 console.log(i); // "set1"
 console.log(val); // [1, 2, 3]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


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