I need to traverse a pretty deep object and I need to extract 12 values in different depths. My plan was to extract with the for of the values for each depth but I have a problem in the first depth.
I am a little confused about the for of behavior.
I thought this:
for (const key of Object.keys(jsonData)){
console.log(i+1);
if (isWantedValue(key))
{
artifactColl[key] = jsonData[key];
}
console.log(key, jsonData[key]);
}
for of loop would run a cycle for each key element that it finds inside the object but the loop is only running once. It prints out all necessary keys with values in the lower console.log function but it calls isWantedValue function only once.
Can please somebody explain that to me?
Object looks like this:
{ searchNGResponse:
{ totalCount: [ '420' ],
from: [ '-1' ],
count: [ '-1' ],
tooManyResults: [ 'false' ],
collapsed: [ 'false' ],
repoDetails: [ [Object] ],
data: [ [Object] ] } }
console output:
1
called with searchNGResponse
searchNGResponse { totalCount: [ '416' ],
from: [ '-1' ],
count: [ '-1' ],
tooManyResults: [ 'false' ],
collapsed: [ 'false' ],
repoDetails: [ { 'xxx': [Object] } ],
data: [ { artifact: [Object] } ] }
Edit: updated
Your jsonData object has only one key, as the console output shows: searchNGResponse.
What you want is the keys of that object, the searchNGResponse object, specifically jsonData.searchNGResponse like this
for (const key of Object.keys(jsonData.searchNGResponse)){
console.log(i+1);
if (isWantedValue(key))
{
artifactColl[key] = jsonData.searchNGResponse[key];
}
console.log(key, jsonData.searchNGResponse[key]);
}
Related
I am trying to create postman tests for an API.
The response I am getting from post man is in a json form. It looks like an Object of arrays.
{
"389": [
[
"2021-04-30T00:00:00Z",
16.130089309443093
]
],
"390": [
[
"2021-04-30T00:00:00Z",
14.899161948201808
]
],
"391": [
[
"2021-04-30T00:00:00Z",
17.495245579925736
]
],
"392": [
[
"2021-04-30T00:00:00Z",
16.78176061001777
]
],
"393": [
[
"2021-04-30T00:00:00Z",
25.473437964096448
]
],
"394": [
[
"2021-04-30T00:00:00Z",
56.746358310562826
]
],
"388": [
[
"2021-04-30T00:00:00Z",
18.49559245290604
]
]
}
I am trying to test the integer value that comes after the date is greater than 0 but cant seem to figure out how to traverse the structure in javascript.
With normal response Jsons they usually have the ID beside them and you can use that value, but not with this response
This is the test so far
pm.test("Check performance > 0", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.value).to.greaterThan(0);
});
It seems you are testing the whole JSON to be > 0. You should loop throught the values :
pm.test("Check performance > 0", function () {
var jsonData = pm.response.json();
Object.values(jsonData).forEach(record => {
pm.expect(record[0][1]).to.greaterThan(0);
});
/* record will be equal to
[
[
"2021-04-30T00:00:00Z",
16.130089309443093
]
]
and then
[
[
"2021-04-30T00:00:00Z",
14.899161948201808
]
]
and so on */
});
Object.values retrieves the values of a dictionary. See Object.values
(if we want the keys ["389", "390", ...] we can use Object.keys)
I have this code from this leetcode question:
function digArtifacts(n: number, artifacts: number[][], dig: number[][]): number {
const land: boolean[][] = new Array(n).fill(new Array(n).fill(false))
console.log(land)
dig.forEach(spot => {
console.log(spot, spot[0], spot[1])
land[spot[0]][spot[1]] = true
console.log(land)
})
console.log(land)
return 0
};
With this input
n = 2
artifacts = [[0,0,0,0],[0,1,1,1]]
dig = [[0,0],[0,1]]
With this stdout:
[ [ false, false ], [ false, false ] ]
[ 0, 0 ] 0 0
[ [ true, false ], [ true, false ] ] **but expected => [ [ true, false ], [ false, false ] ]
[ 0, 1 ] 0 1
[ [ true, true ], [ true, true ] ] **but expected [ [ true, true ], [ false, false ] ]
[ [ true, true ], [ true, true ] ] **but expected [ [ true, true ], [ false, false ] ]
Why do land[1][0] === true and land[1][1] === true when they are never accessed?
This:
new Array(n).fill(new Array(n).fill(false))
fills the new outer array with n copies of the same array. The argument to the outer .fill() is computed once, so there's only one array involved for the second dimension.
You can create multiple arrays, one for each row:
const land: boolean[][] = new Array(n);
land.fill("dummy value");
land.forEach((_, i, rows) =>
rows[i] = new Array(n);
rows[i].fill(false)
);
In the (edited) code, the outer array is first filled with a dummy value. That's necessary because .forEach() will skip uninitialized entries in an array. Alternatively, a simple for loop could be used, though unless n is enormous it probably doesn't matter.
I know there have been some similar questions before but I'm really stuck on trying to map the below array of information (I've tried to implement several example). I have an Array with two information fields and a third field that contains Arrays of objects. I want to extract the name of each of the objects into the original name so that my output looks like the below:
Desired Output:
[gameId, gameName, gameGenresArray]
Below is a sample of what the data looks like:
Data = [ 270722, 'The Wild at Heart', [ [Object], [Object], [Object] ] ],
[ 558984, 'Knockout City', [ [Object] ] ],
[ 558982, 'Miitopia', [ [Object], [Object] ] ],
[ 45775, 'Biomutant', [ [Object], [Object] ] ]
The [Object] has a property called gameGenre that I want to store in the original array as an array instead of as an Array of Objects.
My most recent attempt was:
var result = data.map(({ id, name, [{gameGenres}] }) => ([id, name, gameGenres]))
I appreciate any help anyone can add!
Thanks!!
I think this is what you want:
const Data = [
[
270722,
'The Wild at Heart', [{
name: 'action'
}, {
name: 'horror'
}, {
name: 'adventure'
}],
],
[558984, 'Knockout City', [{
name: 'action'
}]],
[558982, 'Miitopia', [{
name: 'action'
}, {
name: 'rpg'
}]],
[45775, 'Biomutant', [{
name: 'casual'
}, {
name: 'platform'
}]],
];
const result = Data.map(item => {
return {
gameId: item[0],
gameName: item[1],
gameGenresArray: item[2].map(genre => genre.name),
};
});
console.log(result);
You need to map each object and then - when you have an array in an object - map within the map. Easiest to save them in variables:
let gameid, gamename, gamegenre;
Data.map((game) => {gameid=game.id;
gamename=game.name;
game.map((genre) => gamegenre+=genre)})
let result = [gameid, gamename, gamegenre]
Probably needs to be modified, but I don't know how you objects looks.
I'm working on a project for myself (gotta keep busy). I have JavaScript that taps API, and retrieves data as follows:
{
'2020-12-18:95': {
'45.0': [ [Object] ],
'50.0': [ [Object] ],
'55.0': [ [Object] ],
'60.0': [ [Object] ]
}
}
How do I enumerate through that? When I
object.2020-12-18:95
to get to the strike prices, I get error mesg. Your help is appreciated 😀
You can try using Object.keys() and .map() to iterate through as:
const data = {
'2020-12-18:95': {
'45.0': [ {} ],
'50.0': [ {} ],
'55.0': [ {} ],
'60.0': [ {} ]
}
}
const result = data['2020-12-18:95']
Object.keys(result)
.map(key => console.log(key, result[key]))
From the documentations:
The Object.keys() method returns an array of a given object's own enumerable property names, iterated in the same order that a normal loop would.
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.
I'm trying to get an array filled with the info back from some requests made to different REST APIs.
I thought about using Promise.all to do that but for some reason, it yields an Array with a bunch of undefined inside.
[ undefined, undefined, undefined, undefined ]
Here's my code:
var _ = require("lodash");//Used exclusively to check if the result from the request is an object
var ccxt = require("ccxt");//External library used to make the requests
let pairs = ["ETH/EUR", "BTC/EUR", "LTC/EUR", "BCH/EUR"]; //Array on which the Promise.all is based
function test(p) {
for (var i = 0; i < ccxt.exchanges.length; i++) { //Looping through all the rest APIs
let exchange = new ccxt[ccxt.exchanges[i]](); //Defining each API to make the requests
if (exchange.hasFetchOrderBook) {
exchange //Beginning of the request
.fetchOrderBook(p)
.then(order => {
if (_.isObject(order) && order.bids[0][1]) {
let now = Math.floor(new Date());
order.mkt = exchange.name;
order.pair = p;
order.ping = now - order.timestamp;
return order; //Return the result of the request
}
})
.catch(e => {});
}
}
}
Promise.all(pairs.map(test)) //Making the requests based on the Pairs Array
.then(res => {
console.log(res); //Logging the results ==> [undefined, undefined, undefined, undefined] for some reason...
})
.catch(e => {
console.log(e);
});
I know that the requests are correctly being made since if I console.log the order within the loop, I get the correct results -- Example of the result when logging:
{ bids:
[ [ 12009.52, 0.0468 ],
[ 12008.5, 0.0227 ],
[ 12007.48, 30.9321 ],
[ 12006.46, 0.0537 ],
[ 12005.45, 0.0157 ],
[ 12004.43, 7.1659 ],
[ 12003.41, 0.0164 ],
[ 12002.39, 23.4159 ],
[ 12001.38, 0.0284 ],
[ 12000.36, 0.0132 ],
[ 11999.34, 0.0194 ],
[ 11998.33, 0.0034 ],
[ 11997.31, 7.526 ],
[ 2445.72, 34.075 ],
[ 2445.17, 25.4842 ],
[ 2444.96, 0.1118 ],
[ 2444.75, 23.288 ],
[ 2444, 0.0247 ],
[ 2443.8, 0.192 ],
[ 765.51, 0.0828 ] ],
asks:
[ [ 12048.74, 2.523 ],
[ 12049.77, 0.0159 ],
[ 12050.79, 0.029 ],
[ 12051.82, 0.0061 ],
[ 12052.84, 0.0181 ],
[ 12053.87, 0.0164 ],
[ 12054.89, 0.0355 ],
[ 12055.92, 0.0042 ],
[ 13419.62, 0.0063 ],
[ 13420.64, 0.0174 ],
[ 13421.78, 0.0143 ],
[ 13422.92, 0.026 ],
[ 13424.06, 0.0055 ],
[ 13425.2, 14.4552 ],
[ 13426.23, 0.0065 ],
[ 13427.25, 0.0057 ],
[ 13428.39, 0.0147 ],
[ 13429.53, 4.0375 ],
[ 13430.56, 23.9541 ],
[ 13431.58, 0.0137 ] ],
timestamp: 1512845715447,
datetime: '2017-12-09T18:55:15.447Z',
mkt: 'LakeBTC',
pair: 'BTC/EUR',
ping: 0 }
So I guess that the problems I'm dealing with has to do with the asynchronous character of the function... but I'm not sure how I can make it synchronous.
Again, just to try to clarify my question: The objective is to get an array with 4 different types of object (one per pair --> array) so that I can operate on each.
Just to make it clearer, here's an illustration of what I'm trying to achieve:
[
[
Object1,
Object2,
Object3,
etc...
],
[
Object1,
Object2,
Object3,
etc...
],
[
Object1,
Object2,
Object3,
etc...
],
[
Object1,
Object2,
Object3,
etc...
]
]
Why is Promise.all returning the array without waiting on the requests'results?
I hope that was clear enough! If not let mw know! :P
Thanks in advance for your help!
Your test function does return a undefined. You need to return a promise for the result:
function test(p) {
return Promise.all(ccxt.exchanges.map(api => { //Looping through all the rest APIs
//^^^^^^^^^^^^^^^^^^
let exchange = new ccxt[api](); //Defining each API to make the requests
if (exchange.hasFetchOrderBook) {
return exchange //Beginning of the request
.fetchOrderBook(p)
.then(order => {
if (_.isObject(order) && order.bids[0][1]) {
let now = Math.floor(new Date());
order.mkt = exchange.name;
order.pair = p;
order.ping = now - order.timestamp;
return order; //Return the result of the request
}
// else undefined
})
.catch(e => {}); // undefined
}
// else undefined
}));
}
Of course your promises still fulfill with undefined when the if conditions do not apply or an error happens.