Цикл через JSON с помощью node.js - PullRequest
46 голосов
/ 29 апреля 2011

У меня есть файл JSON, который нужно перебрать, как показано ниже ...

{
    "device_id": "8020",
    "data": [{
        "Timestamp": "04-29-11 05:22:39 pm",
        "Start_Value":  0.02,
        "Abstract": 18.60,
        "Editor": 65.20
    }, {
        "Timestamp": "04-29-11 04:22:39 pm",
        "End_Value":  22.22,
        "Text": 8.65,
        "Common": 1.10,
        "Editable": "true",
        "Insert": 6.0
    }]
}

Ключи в данных не всегда будут одинаковыми (я только что использовал примеры, есть 20 различных ключей), и поэтому я не могу настроить свой сценарий для статической ссылки на них для получения значений.

В противном случае я мог бы заявить

var value1 = json.data.Timestamp;
var value2 = json.data.Start_Value;
var value3 = json.data.Abstract;
etc

В прошлом я использовал простой цикл foreach на узле данных ...

foreach ($json->data as $key => $val) {
    switch($key) {
        case 'Timestamp':
            //do this;
        case: 'Start_Value':
            //do this
    }
}

Но не хочу блокировать скрипт. Есть идеи?

Ответы [ 9 ]

77 голосов
/ 29 апреля 2011

Вы можете перебирать объекты JavaScript следующим образом:

for(var attributename in myobject){
    console.log(attributename+": "+myobject[attributename]);
}

myobject может быть вашим json.data

22 голосов
/ 29 апреля 2011

Вы также можете использовать hasOwnProperty в цикле.

for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) {
        switch (prop) {
            // obj[prop] has the value
        }
    }
}

node.js является однопоточным, что означает, что ваш скрипт будет блокировать, хотите вы этого или нет. Помните, что V8 (движок Javascript от Google, который использует node.js) компилирует Javascript в машинный код, что означает, что большинство основных операций действительно быстрые, и цикл по объекту с 100 ключами, вероятно, займет пару наносекунд?

Однако, если вы делаете намного больше внутри цикла и не хотите, чтобы он блокировал прямо сейчас , вы могли бы сделать что-то вроде этого

switch (prop) {
    case 'Timestamp':
        setTimeout(function() { ... }, 5);
        break;
    case 'Start_Value':
        setTimeout(function() { ... }, 10);
        break;
}

Если ваш цикл выполняет очень интенсивную загрузку процессора, вам нужно будет запустить дочерний процесс , чтобы выполнить эту работу или использовать веб-работников .

18 голосов
/ 19 сентября 2011

Я бы порекомендовал воспользоваться тем, что nodeJS всегда будет ES5.Помните, что это не те браузеры, от которых вы можете зависеть от стабильности языка.Тем не менее, я бы рекомендовал не использовать цикл for-in в nodeJS, если вы действительно не хотите делать глубокую рекурсию по цепочке прототипов.Для простых традиционных циклов я бы порекомендовал хорошо использовать метод Object.keys в ES5.Если вы посмотрите следующий тест JSPerf , особенно если вы используете Chrome (поскольку он имеет тот же механизм, что и nodeJS), вы получите приблизительное представление о том, насколько более эффективен этот метод, чем использованиев цикле (примерно в 10 раз быстрее).Вот пример кода:

 var keys = Object.keys( obj );
 for( var i = 0,length = keys.length; i < length; i++ ) {
     obj[ keys[ i ] ];
 }
6 голосов
/ 29 апреля 2011

Если вы хотите избежать блокировки, которая необходима только для очень больших циклов, оберните содержимое вашего цикла в функцию, которая называется следующим образом: process.nextTick(function(){<contents of loop>}), которая будет откладывать выполнение до следующего тика, предоставляя возможность дляожидающие вызовы из других асинхронных функций для обработки.

3 голосов
/ 10 ноября 2015

Если мы используем nodeJS, мы определенно должны использовать различные библиотеки, которые он предоставляет. Встроенные функции, такие как each (), map (), redu () и многие другие из underscoreJS, сокращают наши усилия. Вот образец

    var _=require("underscore");
    var fs=require("fs");

    var jsonObject=JSON.parse(fs.readFileSync('YourJson.json', 'utf8'));


    _.map( jsonObject, function(content) {
        _.map(content,function(data){
           if(data.Timestamp)
              console.log(data.Timestamp)          
           })
      })
2 голосов
/ 04 декабря 2012

Не уверен, поможет ли это, но похоже, что здесь может быть библиотека для асинхронной итерации в узле:https://github.com/caolan/async

Async - это служебный модуль, который предоставляет простые мощные функции для работы с асинхронным JavaScript.Хотя изначально он был разработан для использования с node.js, он также может использоваться непосредственно в браузере.

Async предоставляет около 20 функций, которые включают в себя обычные «функциональные» подозреваемые (map, Reduce, Filter, forEach…)а также некоторые распространенные схемы асинхронного управления потоком (параллель, серия, водопад…).Все эти функции предполагают, что вы следуете соглашению node.js, предусматривающему один обратный вызов в качестве последнего аргумента вашей асинхронной функции.

1 голос
/ 09 декабря 2017

Мой самый предпочтительный способ -

var objectKeysArray = Object.keys(yourJsonObj)
objectKeysArray.forEach(function(objKey) {
    var objValue = yourJsonObj[objKey]
})
1 голос
/ 04 декабря 2012

Посмотрите на Траверс. Он будет рекурсивно обходить дерево объектов для вас, и на каждом узле у вас есть несколько различных объектов, к которым вы можете получить доступ - ключ текущего узла, значение текущего узла, родительский узел текущего узла, полный путь ключа текущего узла и т. Д. *https://github.com/substack/js-traverse. Я использовал это для хорошего воздействия на объекты, к которым я хотел очистить циклические ссылки, и когда мне нужно было выполнить глубокое клонирование при преобразовании различных битов данных. Вот некоторый код, извлеченный из их примеров, чтобы дать вам представление о том, что он может делать.

var id = 54;
var callbacks = {};
var obj = { moo : function () {}, foo : [2,3,4, function () {}] };

var scrubbed = traverse(obj).map(function (x) {
    if (typeof x === 'function') {
        callbacks[id] = { id : id, f : x, path : this.path };
        this.update('[Function]');
        id++;
    }
});

console.dir(scrubbed);
console.dir(callbacks);
0 голосов
/ 14 июля 2019

Слишком поздно, но я считаю, что требуется дополнительное пояснение, как показано ниже.

Вы можете перебирать массив JSON также с помощью простого цикла, например

for(var i = 0;i< jsonArray.length;i++)
{
    console.log(jsonArray[i].attributename);
}

Если у вас естьjson объект, и вы хотите перебрать все его внутренние объекты, затем вам сначала нужно получить весь массив ключей и перебрать ключи, чтобы получить объекты с именами ключей, такими как

var keys = Object.keys(jsonObject);
for(var i=0,i < keys.length;i++) 
{
    var key = keys[i];
    console.log(jsonObject.key.attributename);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...