i have an empty array and need to append array through a nested for loop.
const arr1=[ [ 1,3 ], [ 5,4 ], [ 8,6, 11 ], [ 15, 19, 12 ] ];
const arr2=[ [21,23],[ 3, 2 ], [ 1,4 ], [ 5, 6 ,11 ] ];
const arr3=[];
console.log('Lost assests counts');
for (let i=0;i<arr1.length;++i)
{
const arrTemp=[]
arrTemp.push(arr1[i].length)
for (let j=i+1;j<arr2.length;++j){
const intersection = arr2[j].filter(element => arr1[i].includes(element));
arrTemp.push(intersection.length)
}
console.log(arrTemp);
}
This returns the below output(this is the output of arrTemp inside the loop):
Instead of the above output, Can I have it like the below way?
[[2,1,1,0],[2,1,1],[3,2],[3]]
Did you just want to push the values to arr3? In that case, instead of printing the value within the loop:
console.log(arrTemp);
Push it to the target array in the loop:
arr3.push(arrTemp);
Then after the loop, print the whole thing:
console.log(arr3);
Full example:
const arr1=[ [ 1,3 ], [ 5,4 ], [ 8,6, 11 ], [ 15, 19, 12 ] ];
const arr2=[ [21,23],[ 3, 2 ], [ 1,4 ], [ 5, 6 ,11 ] ];
const arr3=[];
console.log('Lost assests counts');
for (let i=0;i<arr1.length;++i)
{
const arrTemp=[]
arrTemp.push(arr1[i].length)
for (let j=i+1;j<arr2.length;++j){
const intersection = arr2[j].filter(element => arr1[i].includes(element));
arrTemp.push(intersection.length)
}
arr3.push(arrTemp); // I changed this
}
console.log(arr3); // I added this
Related
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"
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));
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);
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);
When Promise.all completes it returns an array of arrays that contain data. In my case the arrays are just numbers:
[
[ 1, 4, 9, 9 ],
[ 4, 4, 9, 1 ],
[ 6, 6, 9, 1 ]
]
The array can be any size.
Currently I'm doing this:
let nums = []
data.map(function(_nums) {
_nums.map(function(num) {
nums.push(num)
})
})
Is there an alternative way of doing this? Does lodash have any functions that are able to do this?
ES2019 introduced Array.prototype.flat which significantly simplifies this to:
const nums = data.flat();
const data = [
[ 1, 4, 9, 9 ],
[ 4, 4, 9, 1 ],
[ 6, 6, 9, 1 ]
];
const nums = data.flat();
console.log(nums);
Original Answer
Use reduce and concat:
data.reduce(function (arr, row) {
return arr.concat(row);
}, []);
Or alternatively, concat and apply:
Array.prototype.concat.apply([], data);
I would do as follows;
var a = [
[ 1, 4, 9, 9 ],
[ 4, 4, 9, 1 ],
[ 6, 6, 9, 1 ]
],
b = [].concat(...a)
console.log(b)
You actually don't need any sort of library to do it, you can use concat with apply:
Promise.all(arrayOfPromises).then((arrayOfArrays) => {
return [].concat.apply([], arrayOfArrays);
});
If you are using lodash, though, you can use _.flatten(arrayOfArrays) for the same effect.
If using async/await, to expand on #Retsam's answer, you can do it like so
const mergedArray = []
.concat
.apply([], await Promise.all([promise1, promise2, promiseN]));
A real world example I did using the AWS SDK, getting a list of usernames from multiple IAM user groups
const users = await getActiveUsersByGroup(['group1', 'group2'])
async function getActiveUsersByGroup(groups = []) {
getUsersByGroupPromises = groups.map(group => getUsersByGroup(group));
const users = []
.concat
.apply([], await Promise.all(getUsersByGroupPromises)) // Merge (concat) arrays
.map(users => users.UserName); // Construct new array with just the usernames
return users;
}
async function getUsersByGroup(group) {
const params = {
GroupName: group,
MaxItems: 100 // Default
};
const { Users: users } = await iam.getGroup(params).promise();
return users;
}