jQuery: Create an array from JSON - javascript

I have a JSON like this:
{
"default": [
[
1325876000000,
0
],
[
1325876000000,
0
],
[
1325876000000,
0
],
[
1325876000000,
0
]
],
"direct": [
[
1328196800000,
0
],
[
1328196800000,
100
],
[
1328196800000,
0
],
[
1328196800000,
0
]
],
"Sales": [
[
1330517600000,
0
],
[
1330517600000,
0
],
[
1330517600000,
90
],
[
1330517600000,
0
]
],
"Support": [
[
1332838400000,
0
],
[
1332838400000,
0
],
[
1332838400000,
0
],
[
1332838400000,
0
]
]
}
I want to generate array contains the name of each item and the first value of the corresponing array. the result should be like this:
ticks = [["default", 1325876000000],["direct", 1328196800000],["Sales", 1330517600000],["Support", 1332838400000]]
the names like default, direct, sales, supportare dynamic so I can't do jsondata.support
what I tried
ticks = []
for key in jsondata{
arraynew = [];
arraynew.push(key)
}
but I don't know how to push the values?
Help please.

You just need to access the sub-array.
var ticks = [];
for (var key in jsondata) {
ticks.push( [ key, jsondata[key][0][0] ] );
}
The expression jsondata[key] gets you the outer array corresponding to each key. Then, jsondata[key][0] gets you the first of the sub-arrays, and adding the final [0] to that gets you the first value in the first sub-array.
Note that you're not guaranteed to get the keys back in any particular order.

Related

Postman test extract integer variable from object of arrays

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)

JSON Array.Reduce multidimensional

I'm trying to gathering an consolidated sum from this example:
[
[
{"mode":"outcome","id":"318","value":"1000000","opposite":"282"},
{"mode":"outcome","id":"316","value":"1000000","opposite":"280"}
],
[
{"mode":"outcome","id":"318","value":"1000000","opposite":"282"},
{"mode":"outcome","id":"316","value":"1000000","opposite":"280"}
],
[
{"mode":"outcome","id":"318","value":"1000000","opposite":"282"},
{"mode":"outcome","id":"316","value":"1000000","opposite":"280"}
],
[
{"mode":"income","id":"282","value":"3000000","opposite":"318"}
],
[
{"mode":"income","id":"280","value":"3000000","opposite":"316"}
]
]
In the previous sample we have duplicated values and the purposal y sum to compare with another objects in mode "income". Already try with loop but I have a headache in how to compare the outcome mode with income.
I hope to be clear with my question. Thanks.
You could run a nested for loop:
let data = [
[
{"mode":"outcome","id":"318","value":"1000000","opposite":"282"},
{"mode":"outcome","id":"316","value":"1000000","opposite":"280"}
],
[
{"mode":"outcome","id":"318","value":"1000000","opposite":"282"},
{"mode":"outcome","id":"316","value":"1000000","opposite":"280"}
],
[
{"mode":"outcome","id":"318","value":"1000000","opposite":"282"},
{"mode":"outcome","id":"316","value":"1000000","opposite":"280"}
],
[
{"mode":"income","id":"282","value":"3000000","opposite":"318"}
],
[
{"mode":"income","id":"280","value":"3000000","opposite":"316"}
]
];
let x = 0;
data.forEach(e => {
e.forEach(c => {
x = x + parseInt(c["value"])
})
});
console.log('SUM:', x);
Then, you extract the value of x to see the total "values"

How to use a spread or map operator to apply this formula to an array of Uint16 pairs?

I've been trying to better understand the spread and/or map operator, specifically how to apply math using it.
I have an array of two Uint16 number pairs like this:
let randomPairs = [
[ 37096, 65104 ], [ 62271, 3432 ], [ 1191, 43320 ], [ 5388, 16819 ],
[ 52224, 52222 ], [ 61913, 48798 ], [ 52950, 18227 ], [ 23232, 43931 ],
[ 14995, 45924 ], [ 20609, 46597 ], [ 2392, 52582 ], [ 7050, 51498 ],
[ 34253, 11210 ], [ 43376, 41964 ], [ 63238, 34740 ], [ 63254, 56620 ]
]
I would like to use the spread or map operator to apply the following formula to each pair. The formula combines the pair into Uint32, then converts it to a float between 0-1.
(((2**16) * u1) + u2) / ((2 ** 32) - 1)
Where u1 represents the first item in a pair, and u2 represents the second item in the pair.
I don't really know how to do it at all, but here is my code that takes the array and applies the formula using a for loop:
let i,j,temparray,chunk = 2, u1, u2
for (i=0,j=randomPairs.length; i<j; i+=chunk) {
temparray = randomPairs.slice(i,i+chunk);
u1 = temparray[0]
u2 = temparray[1]
let float = (((2**16) * u1) + u2) / ((2 ** 32) - 1)
console.log(float)
}
How can I use a spread or map operator to convert the randomPairs array into an array of the desired floats for each pair?
If Float32Array() could be used somehow, I'm all ears about that as well.
If you want to apply an operation on each element in an array, you can use the map method:
let randomPairs = [
[ 37096, 65104 ], [ 62271, 3432 ], [ 1191, 43320 ], [ 5388, 16819 ],
[ 52224, 52222 ], [ 61913, 48798 ], [ 52950, 18227 ], [ 23232, 43931 ],
[ 14995, 45924 ], [ 20609, 46597 ], [ 2392, 52582 ], [ 7050, 51498 ],
[ 34253, 11210 ], [ 43376, 41964 ], [ 63238, 34740 ], [ 63254, 56620 ]
]
let floats = randomPairs.map(p => {
return (((2**16) * p[0]) + p[1]) / ((2 ** 32) - 1);
});
console.log(floats);
Alternatively, you can use the forEach method if you just want to console.log the output and don't need an array of the resulting float values.
I believe this is what you want :)
myPairs.map(pair => {
const [u1, u2] = pair;
return (((2**16) * u1) + u2) / ((2 ** 32) - 1);
})
Here is an example showing how to use the spread operator and the map function:
let randomPairs = [
[ 37096, 65104 ], [ 62271, 3432 ], [ 1191, 43320 ], [ 5388, 16819 ],
[ 52224, 52222 ], [ 61913, 48798 ], [ 52950, 18227 ], [ 23232, 43931 ],
[ 14995, 45924 ], [ 20609, 46597 ], [ 2392, 52582 ], [ 7050, 51498 ],
[ 34253, 11210 ], [ 43376, 41964 ], [ 63238, 34740 ], [ 63254, 56620 ]
]
function foo(u1, u2) {
console.log((((2**16) * u1) + u2) / ((2 ** 32) - 1));
}
randomPairs.map(e => foo(...e));

Flatten an array grouped by nested elements in JavaScript

I have a tricky question... I have an array looks like this:
[
[ [ 'Attribute1', 'Attribute1Synonym1' ], [ 'Attribute2' ] ],
[ [ 'Attribute3' ] ],
[ [ 'Attribute2' ] ]
]
My result should be:
[
'Attribute1 Attribute2',
'Attribute1Synonym1 Attribute2',
'Attribute3',
'Attribute2'
]
The tricky thing is:
the result array has to grouped by the sub-sub-array
the crux is, the first index is an array(1) of arrays(2) of arrays(3)
and i would to like flatten the array by level 3 (array(3)) and at the result should be every possible combination between the upper level.
At level 2 (the first index) is an array with ('Attribute1' and 'Attribute1Synonym1')
so the result should be:
'Attribute1 Attribute2'
and
'Attribute1Synonym1 Attribute2'
the 'Attribute2' comes from the upper level
if the second index of level 2 ['Attribute2'] has also multiple indexes
for example ['Attribute2Synonym5']
the result should be:
'Attribute1 Attribute2'
'Attribute1Synonym1 Attribute2'
'Attribute1 Attribute2Synonym5'
'Attribute1Synonym1 Attribute2Synonym5'
and so on...
This works against your provided example, but I'm going to guess it's fragile against more complex arrays:
const deep = [ [ [ 'Attribute1', 'Attribute1Synonym1' ], [ 'Attribute2' ] ],
[ [ 'Attribute3' ] ],
[ [ 'Attribute2' ] ] ];
const flat = [];
deep.forEach(element => {
const left = element[0];
const right = element[1];
left.forEach(leftElement => {
if(right){
right.forEach(rightElement => {
flat.push(leftElement + ' ' + rightElement);
});
} else {
flat.push(leftElement);
}
})
});
Maybe like this:
var input_arr=[ [ [ 'Attribute1', 'Attribute1Synonym1' ], [ 'Attribute2' ] ],
[ [ 'Attribute3' ] ],
[ [ 'Attribute2' ] ] ];
var output_arr=[];
for(var key1 in input_arr){
var sub_input_arr=input_arr[key1];
for(var key2 in sub_input_arr){
var sub_sub_input_arr=sub_input_arr[key2];
for(var key3 in sub_sub_input_arr){
output_arr.push(sub_sub_input_arr[key3]);
}
}
}
console.log(output_arr);

Mapping values from two arrays

I am using a text analysis service (pos) which I can pass a string at it tells me whether than string contains verbs, nouns etc.
I have code:
var words = new pos.Lexer().lex(req.body.Text);
var tagger = new pos.Tagger();
var taggedWords = tagger.tag(words);
taggedWords is then passed to a handlebars template and looped through and printed.
If I console.log(taggedWords) I see a multidimensional array eg:
[
[ 'Interest-only', 'RB' ],
[ 'deals', 'NNS' ],
[ 'allow', 'VB' ],
[ 'only', 'RB' ],
[ 'ends', 'NNS' ],
...
...
]
I would like to maintain a separate array which maps the values in the above array to human-readable version:
[
['RB', 'adjective'],
['NNS', 'noun'],
['VB', 'verb'],
...
...
]
and then be able to rewrite so that the original array (taggedWords) looks like:
[
[ 'Interest-only', 'adjective' ],
[ 'deals', 'noun' ],
[ 'allow', 'verb' ]
]
and then pass this new array to my template. What is the most efficient way to do this?
var taggedWords = [
[ 'Interest-only', 'RB' ],
[ 'deals', 'NNS' ],
[ 'allow', 'VB' ],
[ 'only', 'RB' ],
[ 'ends', 'NNS' ]
];
var dico = {
'RB' : 'adjective',
'NNS' : 'noun',
'VB' : 'verb'
};
taggedWords.forEach( elt => { elt[1] = dico[elt[1]] });
console.log(taggedWords);
You can use map() to create a new array with modified elements from your original. This code changes the second item in each tagged word to what is listed in the dictionary for that tag.
let taggedWords = [
[ 'Interest-only', 'RB' ],
[ 'deals', 'NNS' ],
[ 'allow', 'VB' ],
[ 'only', 'RB' ],
[ 'ends', 'NNS' ]
];
let dict = [
['RB', 'adjective'],
['NNS', 'noun'],
['VB', 'verb']
];
let result = taggedWords.map(tag => {
tag[1] = dict.find(item => item[0] === tag[1])[1];
return tag;
});
console.log(result);
Brute force method would involve going through all the elements in the arrays and find a match for them in another array and push them into a third array. This will require that you don't have the same tag word in an array twice; ie: 'RB', or 'NNS'. Hope this solves your problem for now. The benefits to this method as apposed to the previous answer would be that the order of items in arrays don't matter since you're comparing each element to every other element in the other array.
let array1 = [
[ 'Interest-only', 'RB' ],
[ 'deals', 'NNS' ],
[ 'allow', 'VB' ],
[ 'only', 'RB' ],
[ 'ends', 'NNS' ]
];
let array2 = [
['RB', 'adjective'],
['NNS', 'noun'],
['VB', 'verb'],
];
let array3 = [];
array1.forEach(el =>
{
array2.forEach(par =>
{
if (el[1] === par[0])
{
array3.push([el[0], par[1]])
}
})
});
console.log(array3);

Categories