简体   繁体   中英

filter javascript array on multiple conditions

I have an input box that filters an array and only shows those matches.

let songs = [
   {name: 'Let It Be', artist: 'The Beatles},
   {name: 'Lady Madonna', artist: 'The Beatles },
   {name: 'Mama Mia', artist: 'The Beatles}
];

In the following example it will just match by name.

let value = 'name';
let q = 'Let it be' // value entered in input box;

let songFilter = songs.filter(function(song) {
   return song[value].toString().toLowerCase().indexOf(q) != -1; // returns true or false
});

Then when I enter Let It Be into the input box it will show return just 'Let It Be' . However, I want to filter by two songs, so if I enter Let It Be, Lady Madonna I would like it to return two songs.

I have taken many approaches but cannot figure out how to get this working. I also have lodash available if this makes it easier to solve.

let songFilter = songs.filter(function(song) {
    ['let it be', 'lady madonna'].indexOf(song[value].toString().toLowerCase()) > -1
});

You could use a Set to key the entries (after split ) that have been input. That way you can see in constant time whether there is a match. Here that Set is passed to filter as the context, so it can be referenced with this :

 let songs = [ {name: 'Let It Be', artist: 'The Beatles' }, {name: 'Lady Madonna', artist: 'The Beatles' }, {name: 'Mama Mia', artist: 'The Beatles' } ]; function find(byKey, valueCsv) { return songs.filter(function(song) { return this.has(song[byKey].toLowerCase()) }, new Set(valueCsv.trim().toLowerCase().split(/\\s*,\\s*/))); } songInput.addEventListener('input', function() { matches.textContent = JSON.stringify(find('name', songInput.value), null, 2); }); 
 Type song name(s):<input id="songInput" style="width:100%"> <pre id="matches"></pre> 

using Array#filter and Array#find

 let songs = [ {name: 'Let It Be', artist: 'The Beatles'}, {name: 'Lady Madonna', artist: 'The Beatles' }, {name: 'Mama Mia', artist: 'The Beatles'} ]; let value = 'name'; let q = 'Let it be,Lady Madonna' // value entered in input box; let splitQ = q.split(',').map(sq=>sq.toLowerCase()); let songFilter = songs.filter(s=>splitQ.find(sq=>s[value].toLowerCase().indexOf(sq) > -1 ) !== undefined ); console.log(songFilter); 

As I said in the comment above:

 let songs = [ {name: 'Let It Be', artist: 'The Beatles'}, {name: 'Lady Madonna', artist: 'The Beatles'}, {name: 'Mama Mia', artist: 'The Beatles'} ]; let value = 'name'; let q = 'Let it be, Lady madonna'; // First: split the q value into multiple songs (and make them lowercased) let qSongs = q.split(', ').map(e => e.toLowerCase()); // Second: filter song that are in the above resultant array (qSongs) // for each song in the songs array let songFilter = songs.filter(song => // see if there is some qsong in the qSongs array such that the value of song is equal to qsong qSongs.some(qsong => song[value].toLowerCase().indexOf(qsong) != -1 ) ); console.log(songFilter); 

 let songs = [ { name: 'Let It Be', artist: 'The Beatles' }, { name: 'Lady Madonna', artist: 'The Beatles' }, { name: 'Mama Mia', artist: 'The Beatles' } ]; let value = 'name'; let q = 'Let it be, Lady madonna'; let songFilter = _.filter(songs, (song) => { let regex = new RegExp(q.replace(/\\s*,\\s*/g, '|'), 'gi'); return regex.test(song[value]); }); console.log(songFilter); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM