Shah Shishir
Shah Shishir

Reputation: 191

How to extract data from a complex Javascript object?

Suppose, I have a simple following code snippet of Javascript.

let data = {
    "ethusd": {
        "at": 1581416882,
        "ticker": {
            "buy": "218.87",
            "sell": "219.0",
            "low": "0.0",
            "high": "0.0",
            "open": 209.09,
            "last": "0.0",
            "volume": "72877.8789",
            "avg_price": "213.699103431748658920247612509",
            "price_change_percent": "-100.00%",
            "vol": "72877.8789"
        }
    },
    "trstusd": {
        "at": 1581416882,
        "ticker": {
            "buy": "0.0",
            "sell": "0.0",
            "low": "0.0",
            "high": "0.0",
            "open": "0.0",
            "last": "0.0",
            "volume": "0.0",
            "avg_price": "0.0",
            "price_change_percent": "+0.00%",
            "vol": "0.0"
        }
    },
    "trsteth": {
        "at": 1581416882,
        "ticker": {
            "buy": "0.0",
            "sell": "0.0",
            "low": "0.0",
            "high": "0.0",
            "open": "0.0",
            "last": "0.0",
            "volume": "0.0",
            "avg_price": "0.0",
            "price_change_percent": "+0.00%",
            "vol": "0.0"
        }
    }
}


for (let element in data)
{
	let innerElement = data[element];
	
	for (let innerData in innerElement)
	{
		if (innerData !== "at")
		{
			let internalData = innerElement[innerData];

			for (let x in internalData)
			{
				console.log(x,internalData[x]);
			}
		}
	}
}

What I tried on that above code is to get the value of buy and sell in particular. So I wrote a code in that way. Is this a good way to extract data from a javascript object or JSON data format? If not, what are the efficient ways and good practices?

Upvotes: 0

Views: 590

Answers (3)

noamyg
noamyg

Reputation: 3104

As far as readability goes, I'd go with lodash.

  1. If you know the path of that buy and sell keys you're looking for, you can use ._get, i.e.:

    _.get(data, 'ethusd.ticker.buy')
    _.get(data, 'trstusd.ticker.sell')
    
  2. If you do not know the exact path, you can use _.findKey

Regarding efficiency, manual deconstruction would probably be faster as demonstrated here, but we're talking about millions of executions per second on both scenarios... I'm going with readability, once again. :-)

Upvotes: 1

Tarik1322
Tarik1322

Reputation: 90

let data = {
    "ethusd": {
        "at": 1581416882,
        "ticker": {
            "buy": "218.87",
            "sell": "219.0",
            "low": "0.0",
            "high": "0.0",
            "open": 209.09,
            "last": "0.0",
            "volume": "72877.8789",
            "avg_price": "213.699103431748658920247612509",
            "price_change_percent": "-100.00%",
            "vol": "72877.8789"
        }
    },
    "trstusd": {
        "at": 1581416882,
        "ticker": {
            "buy": "0.0",
            "sell": "0.0",
            "low": "0.0",
            "high": "0.0",
            "open": "0.0",
            "last": "0.0",
            "volume": "0.0",
            "avg_price": "0.0",
            "price_change_percent": "+0.00%",
            "vol": "0.0"
        }
    },
    "trsteth": {
        "at": 1581416882,
        "ticker": {
            "buy": "0.0",
            "sell": "0.0",
            "low": "0.0",
            "high": "0.0",
            "open": "0.0",
            "last": "0.0",
            "volume": "0.0",
            "avg_price": "0.0",
            "price_change_percent": "+0.00%",
            "vol": "0.0"
        }
    }
}

let valueOfKeysToFound = ['buy', 'sell'];
let simpleObjSubset = [];

function scrapData(obj, valueOfKeysToFound) {
    if (typeof obj === 'object') {
        let tempValues = {};
        let keyFoundCount = 0;

        for (let property in obj) {
            let value = obj[property];

            if (typeof value === 'object') {
                scrapData(value, valueOfKeysToFound);
            } else if (valueOfKeysToFound.includes(property)) {
                tempValues[property] = value;
                keyFoundCount++;

                if (keyFoundCount == valueOfKeysToFound.length) {
                    simpleObjSubset.push(tempValues);
                    break;
                }
            }
        }
    } 
}

scrapData(data, valueOfKeysToFound);
console.table(simpleObjSubset);

When one say efficient it means robust enough from performance perspective and when one say good practice it is ambiguous from person to person, problem to problem and logic to logic.

The problem you mentioned can be solved by approach I wrote, why I solve it this way? Because

  • I know what each line does.
  • It is flexible to scale.
  • It can check N number of depth.

And most important part whatever you write as a solution must give you enough control to change anything.

Upvotes: 2

stfno.me
stfno.me

Reputation: 916

It depends on what you want to do.

For example, if you have to take all the ticker of each exchange:

for(let exchange in data) {
    var ticker = data[exchange]["ticker"];
    console.log(ticker);
    // maybe here you can creare row of a table? (example)
}

or..

for(let exchange in data) {
    var ticker = data[exchange].ticker;
    console.log(ticker);
    // maybe here you can creare row of a table? (example)
}

If you want to access the ticker of a specific exchange instead:

var ticker = data["ethusd"]["ticker"];

or..
var ticker = data.ethusd["ticker"];

or..
var ticker = data.ethusd.ticker;

Obviously you have to check if the field exists:

var exist = typeof data.ethusd !== 'undefined' && data.ethusd !== null;

or..
var exist = typeof data["ethusd"] !== 'undefined' && data["ethusd"] !== null;

or..
var exist = (!!data.ethusd);

or..
var exist = (!!data["ethusd"]);

This is a simple Javascript object, you can access it through the object field or via field name as 'key' of dictionary.

Upvotes: 3

Related Questions