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

[
    {
        "name": "list",
        "text": "SomeText1"
    },
    {
        "name": "complex",
        "text": "SomeText2",
        "config": {
            "name": "configItem",
            "text": "SomeText3",
            "anotherObject": {
                "name": "anotherObject1",
                "text": "SomeText4"
            }
        }
    }
]

Я использую этот потрясающий код, чтобы получить все объекты с определенным ключом (http://techslides.com/how-to-parse-and-search-json-in-javascript ) . В моем примере это getObjects(data,'text',''), который вернет все узлы как объект из-за появления текста в качестве ключа.

Моя единственная проблема в том, что мне нужно знать расположение возвращаемого объекта во всем массиве.

Есть ли способ получить это? Или хотя бы глубину объекта в сочетании с массивом?

getObjects(r,'text','')[0] (name = list) -> глубина 1

getObjects(r,'text','')[1] (name = complex) -> глубина 1

getObjects(r,'text','')[2] (name = configItem) -> глубина 2

0
user1021605 30 Янв 2015 в 15:02

2 ответа

Лучший ответ

Вам понадобится что-то в этом роде:

function getObjectsDepth(obj, key, val, depth) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjectsDepth(obj[i], key, val,++depth));    
        } else 
        //if key matches and value matches or if key matches and value is not passed (eliminating the case where key matches but passed value does not)
        if (i == key && obj[i] == val || i == key && val == '') { //
            objects.push(depth);
        } else if (obj[i] == val && key == ''){
            //only add if the object is not already in the array
            if (objects.lastIndexOf(obj) == -1){
                objects.push(depth);
            }
        }
    }
    return objects;
}

Это вернет глубину объекта, но не сам объект, просто передайте 0 или 1 как последний параметр, в зависимости от того, как вы хотите считать. Если вы хотите одновременно и объект, и глубину, вам нужно obj.push({'obj':obj,'depth':depth}).

2
Szabolcs Páll 30 Янв 2015 в 13:21

Измените функцию getObjects следующим образом:

function getObjects(obj, key, val, depth) {
    var objects = [];
    depth = typeof depth !== 'undefined' ? depth : 0;
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            depth ++;
            objects = objects.concat(getObjects(obj[i], key, val, depth));    
        } else 
        //if key matches and value matches or if key matches and value is not passed (eliminating the case where key matches but passed value does not)
        if (i == key && obj[i] == val || i == key && val == '') { //
            objects.push({"obj":obj,"depth": depth});
        } else if (obj[i] == val && key == ''){
            //only add if the object is not already in the array
            if (objects.lastIndexOf(obj) == -1){
                objects.push({"obj":obj,"depth": depth});
            }
        }
    }
    return objects;
} 

Теперь вы получаете глубину и объект.

1
Paulo Segundo 30 Янв 2015 в 12:39