How to .map array elements which nested in another array? - javascript

I have array todos with elements which is also arrays and contain some numbers.
I need to pass through all arrays, how can I do this with .maps() ?
todos = [
[23, 25],
[33, 36],
[55, 66],
]
console.log(todos.map(el => el.map(subEl => subEl)));

Simply: todos.flat().map(x => x)

you were pretty close but applied the function at the wrong point
I believe this is what you're looking for console.log(todos.map(el => el.map(subEl => subEl)));
todos = [
[23, 25],
[33, 36],
[55, 66],
]
todos.map(el => el.map(subEl => console.log(subEl)));

Related

How to calculate the average value of the properties of an object?

How can I calculate the average value of the properties of an object?
I have this object:
let components = {
co: [235, 465, 78],
no: [409, 589, 98],
nh3: [54, 76, 39]
};
I need to separately calculate the average for co, no, and nh3.
You could get the entries and build a new object with averages.
const
getAverage = array => array.reduce((a, b) => a + b) / array.length,
components = { co: [235, 465, 78], no: [409, 589, 98], nh3: [54, 76, 39] },
result = Object.fromEntries(Object
.entries(components)
.map(([k, v]) => [k, getAverage(v)])
);
console.log(result);
I have corrected your invalid object and tried to get the average values in an array:
let components = {
co: [235, 465, 78],
no: [409, 589, 98],
nh3: [54, 76, 39]
};
let result = [];
Object.keys(components).forEach(function (key) {
avg = components[key].reduce((a, b) => a + b, 0) / components[key].length;
result.push(avg);
});
console.log(result);
Have a proper object
you can use reduce/length
I use a trick to shorten the decimals, toFixed with a unary plus to convert back to number
There are more tricks here. The object.assign converts the array of object to one object using the ... spread operator
const components = {
"co": [235, 465, 78],
"no": [409, 589, 98],
"nh3": [54, 76, 39]
}
const avgs = Object
.assign({},
...Object.entries(components)
.map(([key,values]) =>
({[key]: +(values
.reduce((a,b)=>a+b)/values.length)
.toFixed(2)})
)
);
console.log(avgs)

Why doesn't JS complier recognize this call to Array.prototype.filter

I am trying to figure out why my call to .prototype.filter is giving me a TypeError: curr.filter is not a function.
const intersection = (arrays) => {
return arrays.reduce((acc, curr) => {
return curr.filter(el => acc.includes(el));
});
};
console.log(intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20]));
To my understanding I am declaring a function const intersection which takes in arrays and then returns the result of calling arrays.reduce which 'reduces' the results of filtering the current value and creating a new array that includes all instances of accumulator acc including the current value curr.
Since filter creates a new array on runtime I figured this would work as is yet it does not. What am I not seeing?
Use array rest parameter to get all parameter as an array. In the given code you are taking just first argument and ignoring the rest.
try this.
const intersection = (...arrays) => {
console.log("arrays: ", arrays);
return arrays.reduce((acc, curr) => {
return curr.filter(el => acc.includes(el));
});
};
console.log("Result:" , intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20]));

How to create a variable that is the lowest possible number?

What I have here is an algorithm that finds the highest value in each subarray and pushes it onto a separate array (final).
I want to let the variable 'value' equal to the lowest possible number so that any negative number can be considered higher than 'value'
function largestOfFour(arr) {
var final=[];
arr.map(sub => {
let value = 0; //issue
sub.map(num => {
if(num>value){value=num};
})
final.push(value)
})
return final;
}
console.log(largestOfFour([[17, 23, 25, 12], [25, 7, 34, 48], [4, -10, 18, 21], [-72, -3, -17, -10]]));
In this example the last subarray returns 0 since non of the numbers in that subarray were higher than the initial value of 'value' which is 0.
I want it to return '-3' instead since it's the highest number in the subarray.
It would appear you're simply looking for the max of each array.
Using Array#map and Math#max and spread syntax you could do something like this.
const data = [[17, 23, 25, 12], [25, 7, 34, 48], [4, -10, 18, 21], [-72, -3, -17, -10]];
const res = data.map(arr=>Math.max(...arr));
console.log(res);
You can just set value to Number.NEGATIVE_INFINITY but for what it's worth, I'd recommend simply using reduce instead of map in your inner function. That way, the inner loop will start with sub[0] as an initial value rather than depending on any placeholder.
function largestOfFour(arr) {
var final = arr.map(sub => sub.reduce((num, value) => Math.max(num, value)));
return final;
}
console.log(largestOfFour([
[17, 23, 25, 12],
[25, 7, 34, 48],
[4, -10, 18, 21],
[-72, -3, -17, -10]
]));

Sort JS object of objects(nested)

let tags = {
"01": {
contentID: [10, 20],
occurrences: 1
},
"02": {
contentID: [10, 20],
occurrences: 1
},
"04": {
contentID: [10, 20],
occurrences: 3
},
"05": {
contentID: [10, 20],
occurrences: 6
}
};
How to sort this in descending order by taking occurrences as base, This is a global variable. So I want to store it in a different object and sort that one with descending order..
You can not sort objects, but you can transform it to array of values:
Object.values(tags).sort((a, b) => b.occurrences - a.occurrences)
The result will be:
[
{
contentID: [10, 20],
occurrences: 6
},
{
contentID: [10, 20],
occurrences: 3
},
{
contentID: [10, 20],
occurrences: 1
},
{
contentID: [10, 20],
occurrences: 1
}
]
However you can sort your keys separately if you need them as well:
Object.keys(tags).sort((a, b) => tags[b].occurrences - tags[a].occurrences)
And your result will be an array ['05', '04', '02', '01']
Kindly note that objects in javascript dont have any sense of order.
However you can create and array to hold your result.
To get it in descending order ,you can do
Object.values(tags).sort((a,b) => b.occurrences - a.occurrences)
Other suggestions to think about this as an array are probably sound. It's not a good idea to think of Javascript objects as ordered, even though there is a key-ordering specification. But, if you want to keep the results in the same format, you can do so, and still end up sorting the keys:
let tags = {"01": {"contentID": [10, 20], "occurrences": 1}, "02": {"contentID": [10, 20], "occurrences": 1}, "04": {"contentID": [10, 20], "occurrences": 3}, "05": {"contentID": [10, 20], "occurrences": 6}}
const sorted = Object.entries(tags).sort(([, {occurrences: a}], [, {occurrences: b}]) => b - a)
.reduce((a, [k, v]) => Object.assign(a, {[k]: v}), {})
console.log(sorted)
I can't see what this is really good for, though. The only place you can see a difference in behavior is if you use something like Object.keys, Object.values, or Object.entries on it, again creating arrays.

Iterate over multi-dimensional array and return aggregated sum based on first index

I've really been wrecking my brain over this one so any assistance is greatly appreciated. I currently have an array of objects and each of these objects has two properties, a timestamp (ms since epoch) and an arbitrary for that timestamp. Like so:
[
[1518739200000, 1],
[1518739200000, 1],
[1518739200000, 12],
[1518739200000, 16],
[1518739200000, 16],
[1518825600000, 16],
[1518825600000, 20],
[1518825600000, 20],
[1518825600000, 8],
]
What I'm trying to do is to condense the multidimensional array into another multidimensional array which has only the unique values of the first index, the timestamp, and an aggregate count as the second value. In example, I'm looking for this from the given set of data included above.
[
[1518739200000, 46],
[1518825600000, 64],
]
I've tried using .reduce in a few ways but haven't had any success yet for this particular kind manipulation.
An alternative using the function reduce
let array = [[1518739200000, 1], [1518739200000, 1],[1518739200000, 12],[1518739200000, 16],[1518739200000, 16],[1518825600000, 16],[1518825600000, 20],[1518825600000, 20],[1518825600000, 8]];
let result = Object.values(array.reduce((a, [key, value]) => {
(a[key] || (a[key] = [key, 0]))[1] += value;
return a;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could reduce the array to a Map and use the Map to create an array of arrays using Array.from.
var data = [
[1518739200000, 1],
[1518739200000, 1],
[1518739200000, 12],
[1518739200000, 16],
[1518739200000, 16],
[1518825600000, 16],
[1518825600000, 20],
[1518825600000, 20],
[1518825600000, 8],
];
console.log(
Array.from(
data.reduce(
(result,[current,num])=>
result.set(
current,
(result.get(current)||0)+num
),
new Map()
)
)
)
Use reduce
var x = [
[1518739200000, 1],
[1518739200000, 1],
[1518739200000, 12],
[1518739200000, 16],
[1518739200000, 16],
[1518825600000, 16],
[1518825600000, 20],
[1518825600000, 20],
[1518825600000, 8],
]
x.reduce(function(ac,d,i,a){if(!ac.some(function(dd,ii){return dd[0] === d[0] && dd[1] === d[1]})){ac.push(d)
}return ac},[]);
The above gets unique values for BOTH indexes, for the first one only:
x.reduce(function(ac,d,i,a){if(!ac.some(function(dd,ii){return dd[0] === d[0]})){ac.push(d)}return ac},[])
But then, the question is, this gets the first encountered entry, do you have any preference for the second?
UPDATE:Oww, I didn't see the aggreate, this is for it:
x.reduce(function(ac,d,i,a){
var index;
if(
!ac.some(function(dd,ii){
return dd[0] === d[0] ? (index=ii,true) : false
})
){
ac.push(d.slice())
} else {
ac[index][1] += d[1];
}
return ac
},[])

Categories