最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Array filter with possible undefined properties - Stack Overflow

programmeradmin1浏览0评论

I have an array of objects that may or not contain a property.

So, in order to filter it, I do this:

array = array.filter(v => v.myproperty != undefined);
array = array.filter(v => v.myproperty[0] != undefined);

This effectively removes the ones where myproperty is undefined and, afterwards, the ones where the first element inside myproperty.

Is there a way of having a single liner that prevents me from applying filter to the array twice?

Something like:

array = array.filter((v => v.myproperty || [])[0] != undefined);

I have an array of objects that may or not contain a property.

So, in order to filter it, I do this:

array = array.filter(v => v.myproperty != undefined);
array = array.filter(v => v.myproperty[0] != undefined);

This effectively removes the ones where myproperty is undefined and, afterwards, the ones where the first element inside myproperty.

Is there a way of having a single liner that prevents me from applying filter to the array twice?

Something like:

array = array.filter((v => v.myproperty || [])[0] != undefined);
Share Improve this question asked Aug 23, 2017 at 16:12 chiapachiapa 4,41211 gold badges70 silver badges108 bronze badges 8
  • 5 Wouldn't array = array.filter(v => v.myproperty != undefined && v.myproperty[0] != undefined); work? – Blorgbeard Commented Aug 23, 2017 at 16:14
  • No, that would error: "myproperty is not defined" as it is trying to access index 0 of something undefined – chiapa Commented Aug 23, 2017 at 16:18
  • 3 But && short-circuits, right? If myproperty is undefined, myproperty[0] will not be evaluated. – Blorgbeard Commented Aug 23, 2017 at 16:20
  • 1 No problem. But you might want to double-check C#'s behaviour on this, because it definitely short-circuits && too. – Blorgbeard Commented Aug 24, 2017 at 14:47
  • 1 That example is bad.. && can't short-circuit (in C# or javascript) when the first argument evaluates to true. It doesn't even make sense to say "if something is null AND something.property is null". A better example: dotnetfiddle/CxJPAw - note no NPE. – Blorgbeard Commented Aug 25, 2017 at 15:34
 |  Show 3 more ments

6 Answers 6

Reset to default 3

In the end, array.filter() takes an anonymous function that is expecting a boolean result. You can do any amount of work inside to determine if the array item should be filtered.

var array = [1, 2, undefined, 3, "some text", [5,6,7],[], [undefined,8]]

array = array.filter(v => {

  if (!v) return false;

  if (v === "some text") return false;
  
  if (Array.isArray(v) && v.length === 0) return false;
  
  if (Array.isArray(v) && v[0] === undefined) return false;

  return true;

});


console.log(array);

What about:

filtered_array = array.filter(element => element.property && element.property[0]);

What the condition do is to evaluate the left part first. If it's true, it will try to evaluate the right part and return the result.

Fiddle here.

You can do what others have already suggested here, the function will return if the first condition fails.

    array => array.filter(v => v.ggwp && v.ggwp[0])

You can also use the in operator to acplish the same thing like this:

    array => array.filter(v => ('myproperty' in v) && (0 in v.myproperty))

Here's a jsbin with some testcases that pare these two functions to yours.

I'm not sure though that you want to use != in your code instead of !==. Javascript, because of type coercion has weird behaviour.

Something like array.filter((v => v.myproperty || [])[0] != undefined);

Yes, exactly something like that. You only misplaced one parenthesis:

array.filter( v => (v.myproperty || [])[0] != undefined);
//           ^     ^

You can have plex boolean logic in your statement.

let array = [{num: [1]}, {num: [2]}, {num: [3]}, {num: undefined}, {}]
array = array.filter(v => v && v.num && v.num.length)

For readability and testability you may want to break it out into a function that you can test somewhere else.

function predicate(v) {
  return v && v.num && v.num.length
}
let array = [{num: [1]}, {num: [2]}, {num: [3]}, {num: undefined}, {}]
array = array.filter(predicate)

You should also check if the properties element is an array. Checking for the property only with element.property[0] will also be true for strings. Besides that, you can pass anything returning a boolean inside filter, just like you would do in a if statement.

arr.filter(e => 'myproperty' in e && 
      Array.isArray(e.myproperty) && 
      e.myproperty[0] !== undefined)
发布评论

评论列表(0)

  1. 暂无评论