Reputation: 7822
I have multiple arrays, but some of them have values of 0
or undefined. What I'm trying to do is, every time a condition is true, push the counter
value into a new array.
let array1 = [5, 6, 44, 2, 6];
let array2 = ['', '', '', 5 , 7];
I got this far, but it's returning only unique values. Meaning, let's imagine we have those two arrays above, first having all values - array1, second doesn't - array2 (index 0, 1, 2 is null, but index 3 and 4 has its number values). The function below is returning --> [1, 2]
.
empNum = (data) => {
let activeArr = [];
let activeOnes = 0;
for (let i=0; i<data.length; i++) {
if (active[i] !== 0 && active[i] !== '') {
activeOnes ++;
activeArr.push(activeOnes);
}
}
return activeArr; // [1, 2 ] < -- This is not what I need.
}
In the first three runs, only one array is passing the condition [1, 1, 1], but on the 4th and 5th run both arrays are passing the test, so the next two entries should be [2, 2].
So, what I'm trying to achieve is a new array looking like this - [1, 1, 1, 2, 2]
.
Note: The number of arrays isn't two. There are many others, all the same length, and the number of them (num of arrays) can grow over time, as well as the number of entries inside every single one, but at the end, they all will still have the same length.
Maybe some other type of a loop? Any suggestions?
Upvotes: 2
Views: 66
Reputation: 4814
One approach could be to make a new array for each position you want to count. This makes it easy to count the number of truthy values for each position in the original arrays.
This is fairly straightforward using lodash's zip
:
const array1 = [5, 6, 44, 2, 6];
const array2 = ['', '', '', 5 , 7];
const array3 = [1, '', 0, 1, false]
const zipped = _.zip(array1, array2, array3);
// `zipped` should now look like this, where each element
// is an array that represents all of the elements a given
// position from all of the original arrays.
// [
// [5, "", 1],
// [6, "", ""],
// [44, "", 0],
// [2, 5, 1],
// [6, 7, false],
// ]
const results = _.map(zipped, (array) => {
// lodash doesn't seem to have a `count`, but it does have `countBy`
const counts = _.countBy(array, (element) => new Boolean(element));
// Here `counts` will be an object showing how many items in the array were `true` and how many were `false`.
// For example, in the first iteration, it will look like `{ "false": 1, "true": 2 }`
// So, only return the count that is `true`.
return counts['true'];
});
// Here, the results is:
// [2, 1, 1, 3, 2]
This script can be found at https://runkit.com/amiel/5b22dffb85fb2d00128e2217 if you'd like to run it and see the results.
Upvotes: 1
Reputation: 8740
@Ray, let suppose I assume your both arrays of same length then the below code will work as you want.
Here, the use of ternary operator(conditional operator) ?:
and 2 logical operators &&
, ||
play great roles.The code works for 0
, ''
as well as for undefined
, null
also.
Try it online at http://rextester.com/HYR69124.
// empNum() is a function which takes 2 arrays of same length as parameters
var empNum = (data1, data2) => {
var activeArr = [];
for (var i=0; i<data1.length; i++) {
activeArr.push(data1[i] && data2[i] ? 2 : 1); // Using ternary operator ?:
}
return activeArr;
}
// Test 1
var array1= [5, 6, 44, 2, 6];
var array2 = ['', '', '', 5, 7];
console.log(empNum(array1, array2)); //[ 1, 1, 1, 2, 2 ]
// Test 2
console.log(empNum([5, 0, 44, 2, 6], [8, 7, undefined, 5, 7,] )); // [ 2, 1, 1, 2, 2 ]
// Test 3
console.log(empNum(["JavaScript", 0, undefined, null, 6], [8, 7, undefined, 5, 7,] )); // [ 2, 1, 1, 1, 2 ]
// Test 4
console.log(empNum([0, 0, 44, 2, "Python"], [8, 7, undefined, 5, 7,] )); // [ 1, 1, 1, 2, 2 ]
» Output
[ 1, 1, 1, 2, 2 ]
[ 2, 1, 1, 2, 2 ]
[ 2, 1, 1, 1, 2 ]
[ 1, 1, 1, 2, 2 ]
Upvotes: 0
Reputation: 370859
I think the best thing to do here would be to map
both arrays into a single array, after testing for truthyness:
let array1 = [5, 6, 44, 2, 6];
let array2 = ['', '', '', 5 , 7];
const result = array1.map((item1, i) => {
const item2 = array2[i];
return Boolean(item1) + Boolean(item2); // gets converted to number
});
console.log(result);
That's assuming that the arrays have the same number of elements, of course. If they don't, you might use Math.max
on the lengths of both arrays first.
If you have multiple arrays, put them into a single array first and then iterate over that array:
const arrs = [
[5, 6, 44, 2, 6],
['', '', '', 5 , 7],
];
const { length } = arrs[0];
const result = Array.from(
{ length },
(_, i) => arrs.reduce((a, arr) => a + Boolean(arr[i]), 0)
);
console.log(result);
Or you might prefer to access each sub-array only once:
const arrs = [
[5, 6, 44, 2, 6],
['', '', '', 5 , 7],
];
const { length } = arrs[0];
const result = [];
arrs.forEach(arr =>
arr.forEach((item, i) => result[i] = (result[i] || 0) + Boolean(item))
);
console.log(result);
Upvotes: 2