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

javascript - Combine filter() and startsWith() to filter array - Stack Overflow

programmeradmin2浏览0评论

Suppose I have an array constant as follows:

const people = [
      { first: 'John', last: 'Doe', year: 1991, month: 6 },
      { first: 'Jane', last: 'Doe', year: 1990, month: 9 },
      { first: 'Jahn', last: 'Deo', year: 1986, month: 1 },
      { first: 'Jone', last: 'Deo', year: 1992, month: 11 },
      { first: 'Jhan', last: 'Doe', year: 1989, month: 4 },
      { first: 'Jeon', last: 'Doe', year: 1992, month: 2 },
      { first: 'Janh', last: 'Edo', year: 1984, month: 7 },
      { first: 'Jean', last: 'Edo', year: 1981, month: 8},
];

And I want to return a value of everyone born in the 80s.

My current working function for achieving this is:

const eighty = people.filter(person=> {
    if (person.year >= 1980 && person.year <= 1989) {
        return true;
    }
});

My Question: Is it possible to use startsWith() along with filter() to replace:

if (person.year >= 1980 && person.year <= 1989) {
    return true;
}

with startsWith('198') instead?

If yes, what would be the right way to do it?

Suppose I have an array constant as follows:

const people = [
      { first: 'John', last: 'Doe', year: 1991, month: 6 },
      { first: 'Jane', last: 'Doe', year: 1990, month: 9 },
      { first: 'Jahn', last: 'Deo', year: 1986, month: 1 },
      { first: 'Jone', last: 'Deo', year: 1992, month: 11 },
      { first: 'Jhan', last: 'Doe', year: 1989, month: 4 },
      { first: 'Jeon', last: 'Doe', year: 1992, month: 2 },
      { first: 'Janh', last: 'Edo', year: 1984, month: 7 },
      { first: 'Jean', last: 'Edo', year: 1981, month: 8},
];

And I want to return a value of everyone born in the 80s.

My current working function for achieving this is:

const eighty = people.filter(person=> {
    if (person.year >= 1980 && person.year <= 1989) {
        return true;
    }
});

My Question: Is it possible to use startsWith() along with filter() to replace:

if (person.year >= 1980 && person.year <= 1989) {
    return true;
}

with startsWith('198') instead?

If yes, what would be the right way to do it?

Share Improve this question asked Apr 25, 2018 at 19:54 AndrewL64AndrewL64 16.3k8 gold badges50 silver badges85 bronze badges 6
  • 4 youd have to convert it to a string first...but it would also then cover a year of 19801 for example which is invalid – Ctznkane525 Commented Apr 25, 2018 at 19:54
  • 1 Instead of startsWith, you could avoid the mentioned edge case by matching a regex instead. Maybe /^198\d$/.test(String(year)) – CRice Commented Apr 25, 2018 at 19:56
  • 3 You don’t need this if statement. Just return the condition: people.filter((person) => person.year >= 1980 && person.year <= 1989) or use destructuring: people.filter(({year}) => year >= 1980 && year <= 1989). – Sebastian Simon Commented Apr 25, 2018 at 19:56
  • 1 return Math.floor(person.year / 10) === 198 – castletheperson Commented Apr 25, 2018 at 19:56
  • 2 My basic problem is that these alternate solutions save you like half a line of code, and in exchange it's either a massive overhead (converting to string + checking a substring) compared to a simple value check, or in the case of Math.floor(), it's really unintuitive to read. I'd recommend you go with @Xufox's suggestion and just return the boolean expression instead of using an if branch. – Máté Safranka Commented Apr 25, 2018 at 20:02
 |  Show 1 more comment

3 Answers 3

Reset to default 12

You can do

people.filter(person => String(person.year).startsWith('198'))

const people = [
      { first: 'John', last: 'Doe', year: 1991, month: 6 },
      { first: 'Jane', last: 'Doe', year: 1990, month: 9 },
      { first: 'Jahn', last: 'Deo', year: 1986, month: 1 },
      { first: 'Jone', last: 'Deo', year: 1992, month: 11 },
      { first: 'Jhan', last: 'Doe', year: 1989, month: 4 },
      { first: 'Jeon', last: 'Doe', year: 1992, month: 2 },
      { first: 'Janh', last: 'Edo', year: 1984, month: 7 },
      { first: 'Jean', last: 'Edo', year: 1981, month: 8},
];

var filtered = people.filter(p => String(p.year).startsWith('198'));

console.log(filtered);

This isn't quite what you asked, sorry, but if you're interested in solving the problem in one operation rather than using startsWith specifically, you can do it numerically...

Math.floor(person.year / 10) === 198

It may be slighly more efficient as no string conversion and doesn't have the problems of other strings starting the same way matching.

Yes you can:

people.filter(person => String(person.year).startsWith('198'));

However, you probably don't want to because you could run into weird things where the year isn't valid (like if it was 19812).

Instead, you'd be better off using regex:

people.filter(person => /^198\d$/.test(person.year));

This will only match the years in the 1980s. You also don't have to do the extra cast, so its a little cleaner too.

发布评论

评论列表(0)

  1. 暂无评论