在多个条件下过滤javascript数组

时间:2017-04-04 10:44:12

标签: javascript arrays filter ecmascript-6 lodash

我有一个过滤数组的输入框,只显示那些匹配项。

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' // value entered in input box;

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

然后,当我在输入框中输入Let It Be时,它将显示仅返回'Let It Be'。但是,我希望按两首歌曲进行过滤,所以如果我输入Let It Be, Lady Madonna,我希望它能返回两首歌曲。

我采取了很多方法,但无法弄清楚如何使其发挥作用。如果这样可以更容易解决,我也可以使用lodash

5 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

您可以使用Set来键入已输入的条目(split之后)。这样你就可以在恒定的时间内看到是否有匹配。此处Set作为上下文传递给filter,因此可以使用this引用{<1}}:

&#13;
&#13;
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);
});
&#13;
Type song name(s):<input id="songInput" style="width:100%">
<pre id="matches"></pre>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

使用Array#filterArray#find

&#13;
&#13;
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);
&#13;
&#13;
&#13;

答案 3 :(得分:0)

正如我在上述评论中所说:

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);

答案 4 :(得分:0)

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>