0

This is the log:

0: 89392
1: 4454
2: 196406
3: undefined
4: 181473
5: 35547
6: 26040
7: 102495
8: 96180
9: 20733
10: 33113
11: 86545
12: 25397
13: 4718
14: 40053
15: 51517
16: 9026
17: 26811
18: 63626
19: 18050

Tried:

var casiTestati = filtererdData.map(vd => {
    var testatiValid = vd.data.casi_testati;
    if(testatiValid != "") {
        if(firstRunMap) {
            return vd.data[vd.data.length - 1].casi_testati;
        }
        return vd.data[vd.data.length - 1].casi_testati - vd.data[0].casi_testati;
    }
});

Also tried testing with:

if(!testatiValid) and if(testatiValid = undefined) and if(typeof testatiValid !== 'undefined') {

But I still get undefined value

Actually doing:

if(typeof testatiValid !== 'undefined') {

Gives me all values as undefined

rob.m
  • 9,843
  • 19
  • 73
  • 162

4 Answers4

1

Array#map will always return an array of the same length as the input one - you can't skip any values. There are two easy approaches to this problem.

1. Use an Array#filter after the map to filter out undefined values (may be slow on large data sets as it requires two loops)

var casiTestati = filtererdData.map(vd => {
    var testatiValid = vd.data.casi_testati;
    if(testatiValid != "") {
        if(firstRunMap) {
            return vd.data[vd.data.length - 1].casi_testati;
        }
        return vd.data[vd.data.length - 1].casi_testati - vd.data[0].casi_testati;
    }
}).filter(vd => vd !== undefined); //<-- filter out undefined values

2. Use a normal loop or reduce instead of a map and add values to the result array manually

var casiTestati = filtererdData.reduce((ct,vd) => {
    var testatiValid = vd.data.casi_testati;
    if(testatiValid != "") {
        if(firstRunMap) {
            ct.push(vd.data[vd.data.length - 1].casi_testati);
        }
        ct.push(vd.data[vd.data.length - 1].casi_testati - vd.data[0].casi_testati);
    }
}, []);

Explanation:

From your comments on the other answers, it seems like some of your data has an undefined casi_testati property. You would have to manually check the first and last data[...].casi_testati and simply not push the value in the 2nd case. But in the first case you allow some invalid data and just filter it out afterwards. Both approaches are perfectly OK.

Klaycon
  • 10,599
  • 18
  • 35
  • tried to use the second one and I got (http://example.com) _italic_ **bold** `code(40) [89392, 89392, 4454, 4454, 196406, 196406, undefined, NaN, 181473, 181473, 35547, 35547, 26040, 26040, 102495, 102495, 96180, 96180, 20733, 20733, 33113, 33113, 86545, 86545, 25397, 25397, 4718, 4718, 40053, 40053, 51517, 51517, 9026, 9026, 26811, 26811, 63626, 63626, 18050, 18050](http://example.com) _italic_ **bold** `code – rob.m Apr 24 '20 at 20:49
  • @rob.m It looks like your `casi_testati` property is sometimes undefined. You should check for this and not push values if it is invalid. Or you can use the first approach and just filter out all bad values afterwards. – Klaycon Apr 24 '20 at 20:51
  • ok your first piece works! Damn I want to understand why now, because it doesn't make sense to me – rob.m Apr 24 '20 at 20:51
  • @rob.m I attempted to explain more in the edit, please give it a look and see if it helps. – Klaycon Apr 24 '20 at 20:55
  • this will be a nightmare, now we have another case where we need to use it, but we get NaN `var totCasiTestati = regionData.data[regionData.data.length - 1].casi_testati - regionData.data[0].casi_testati;` – rob.m Apr 24 '20 at 20:56
  • that is within this `filtererdData.forEach((regionData) => {` – rob.m Apr 24 '20 at 20:57
  • @rob.m You're doing a subtraction between `vd.data[vd.data.length-1].casi_testati` and `vd.data[0].casi_testati`. If either of those are undefined, the result of subtraction is NaN. You can either filter out NaN values too with method #1 or perform a check first and don't push any value if it will be NaN in method #2. – Klaycon Apr 24 '20 at 21:03
  • Given how browsers do optimize js, having first a filter then a map might actually be a lot faster on big data. Even though it'll loop two times, the branching you create will force the code to be deoptimized. – Kaiido Apr 25 '20 at 23:52
0

You should filter your results first to get rid of undefined value first: filtererdData.filter(x => x !== undefined).map(x => {...}).

Alex
  • 1,724
  • 13
  • 25
  • this still gives me one undefined `var casiTestati = filtererdData.filter(vd => vd !== undefined).map(vd => { if(firstRunMap) { return vd.data[vd.data.length - 1].casi_testati; } return vd.data[vd.data.length - 1].casi_testati - vd.data[0].casi_testati; }); } console.log(casiTestati);` – rob.m Apr 24 '20 at 20:46
0

Array.prototype.map never removes any values.

You can run Array.prototype.filter first:

var casiTestati = filtererdData.filter(vd => vd !== undefined).map(vd => {
    // your code
});

If you want to do both at the same time, there's also Array.prototype.reduce:

var casiTestati = filtererdData.reduce((carry, item) => {
    if (item === undefined) return carry;

    const newItem = /* your code */;

    carry.push(newItem);
}, []);
Robo Robok
  • 21,132
  • 17
  • 68
  • 126
  • this still gives me one undefined `var casiTestati = filtererdData.filter(vd => vd !== undefined).map(vd => { if(firstRunMap) { return vd.data[vd.data.length - 1].casi_testati; } return vd.data[vd.data.length - 1].casi_testati - vd.data[0].casi_testati; }); } console.log(casiTestati);` – rob.m Apr 24 '20 at 20:46
  • Probably your `.map()` returns `undefined` for some items. – Robo Robok Apr 24 '20 at 20:48
  • it is indeed, check the comment I made for Klaycon, tried his second piece with a normal loop but still – rob.m Apr 24 '20 at 20:50
0

I think your problem is in this line:

var testatiValid = vd.data.casi_testati;

Elsewhere you are treating vd.data as an array. vd.data.casi_testati will always be undefined.

You'll want to move your falsey check to if(vd.data[vd.data.length - 1].casi_testati) or if (vd.data[0].casi_testati). Look at the return values.

sdotson
  • 790
  • 3
  • 13