how to return nothing ( empty array) with array.map function
Asked Answered
L

6

21

Right now, if 'Everything' in the list is detected, the output becomes [""].
Expected output: []

Copy.names = rule.names.map(function(x) {                                
    if (x.name ==='Everything') {                                   
        return '';
    } else {
        return x.name;
    }
});
Lawtun answered 27/6, 2016 at 19:27 Comment(8)
just write return; Also, consider using Array.prototype.filter for this.Lutz
if i do that, it returns 'null' which I don't wantLawtun
You probably want to use a method such as filter. map returns an element for every element you iterate over.Thorn
@Lawtun Change map to filter, return '' to false and return x.name to trueScenography
Or you could simply put return x.name === 'Everything' instead of the whole if...elseScenography
Map will always return SOMETHING, you will need to change it to filter or, using a regular for loop to get the desired behavior.Lutz
guys, my backend expects an empty list [] if "everything" is selected. Otherwise, it expects a list of the other names ['apple', 'orange'] So what's the best way?Lawtun
Possible duplicate of Removing elements with Array.map in JavaScriptChicory
K
18

Use Array.prototype.filter:

Copy.names = rule.names.filter(function(x) {                                
    return x.name !=='Everything';
}).map(function (x) {
    return x.name;
});
Kaiser answered 27/6, 2016 at 19:32 Comment(3)
I did this, it's actually returning 'Everything' , which is wrongLawtun
If you are using the code in your original post, the problem is that Array.prototype.map applies a transformation to every element in your list. You must instead use some logic to remove or ignore elements you don't want. Array.prototype.map does not have the ability to ignore elements alone, so it must be combined with another function, like Array.prototype.filter: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Kaiser
Shouldn't it be x.name !== 'Everything'?Chicory
P
18

Another solution with Array.filter():

names.map(
  (x) => x.name === 'Everything' && x.name
).filter(Boolean)
Plasterboard answered 13/2, 2019 at 12:34 Comment(0)
C
2

If you can use Lodash (which I highly recommend), you can deal with it in elegant way by using _.flatMap:

Copy.names = _.flatMap(rule.names, function(x) {
    if (x.name ==='Everything') {                                   
        return [];
    } else {
        return [x.name];
    }
})

As you can see, it's similiar to map, except that you return array of items instead of item.

Chicory answered 27/6, 2016 at 19:36 Comment(3)
One caveat to this approach is that you will create a temporary array for every element in rule.names. This isn't a big deal for just a few elements, but can become costly with large lists.Kaiser
please dont ever import a heavy dependency for just one function...Oryx
@samthet I think the package gets reduced in the build package to include only the used functionsVaniavanilla
C
2

If you can use ES6, you can use generator for that:

Copy.names = Array.from(function* () {
    for (var x of rule.names) {
       if (x.name ==='Everything') {                                   
            // do nothing
       } else {
            yield x.name;
       }
    }
})

If not... you can always go for imperative way:

Copy.names = []

for (var x of rule.names) {
   if (x.name ==='Everything') {                                   
        // do nothing
   } else {
        Copy.names.push(x.name);
   }
}
Chicory answered 27/6, 2016 at 19:40 Comment(1)
I don't think that the first approach (Using Array.from with generator) works. I tried it in different ES6 enabled environments and it always returns an empty array.Polyzoarium
D
0

An answer I wrote elsewhere covers this, but if you want to be able to accomplish the transform of Array.map() but also to change the output length, you would need to use Array.reduce().

Usually, though, it will make more sense to filter--preferably before you map, but if needed, then after.

Damson answered 2/5, 2020 at 5:59 Comment(0)
R
0

For this you should use reduce instead of map, here an example:

Copy.names = rule.names.reduce(function (arr, x) {
  x.name !== 'Everything' && arr.push(x.name)
  return arr
}, [])
Reinold answered 11/5, 2022 at 19:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.