【问题标题】:Filter array of objects by multiple strings通过多个字符串过滤对象数组
【发布时间】:2018-08-09 01:09:26
【问题描述】:

试着思考我应该如何过滤一组对象并只返回满足所有标签的结果。

标签可以是任何字段 - fname/lname/email/position/etc

let search_tags = ['CEO', 'Steven'];

let contacts = [
  { fname: 'Steve', lname: 'Johnson', email: 'user@domain.com', position: 'CEO' },
  { fname: 'James', lname: 'Laurence', email: 'boss@domain.com', position: 'CFO' }
]

let results = contacts.filter((contact) => {
  if (search_tags.includes(contact.fname) || 
      search_tags.includes(contact.lname) ... ) {
    return contact;
  }
}

为了简洁起见,我缩短了一些代码,显然这个解决方案将返回与 any search_tag 匹配的联系人,但是...我只需要返回满足 every 的结果强>search_tag.

这是漫长的一天,我没有人可以谈论这件事,所以我希望有人能够指出我正确的方向或给我那个啊哈!那一刻我我希望:)

提前致谢!

【问题讨论】:

  • 使用 && 而不是 ||
  • 如果您只是希望被指向正确的方向:将 search_tags 转换为 Set 对象,然后为联系人中的每个对象创建一组字段值,然后进行设置交集或对称差。如果您需要帮助,请告诉我们。

标签: javascript arrays filtering javascript-objects


【解决方案1】:

如果您想返回一个匹配每个搜索标签的代码,您希望使用 && 而不是 ||,但这仍然会给您留下一堆冗长和重复的代码

您可以使用 Object.values() https://mdn.io/objectvalues 而不是直接对联系人对象进行操作,这将为您提供 ['steve', 'johnson', 'user@domain]... 等数组。

然后你可以在你的过滤器中:

contacts.filter((contact) => {
    const contactValues = Object.values(contact);
    // Return the search item if at least one item matches
    // Would return true if at least one item matches
    return contactValues.some(value => search_tags.includes(value));
    // return true only if all search tags match
    return contactValues.every(value => search_tags.includes(value));
}

Object.values 是一个相当新的特性,所以如果你在 babel 中没有它,那么你可以使用 Object.keys 并使用 contact[someKey] 获取值

【讨论】:

  • 您的第二次退货将永远不会被击中。
  • @Geuis 我认为它被包含在一个“模板”中,并且预计 OP 将保留两者之一
【解决方案2】:

Array.prototype.filter() 可以与Array.prototype.every()Object.values()Array.prototype.includes() 组合以构造matchesArray,仅由contact Objects 组成,其中每个@ 都包含一个匹配的value 987654334@search_tags.

请参阅下面的实际示例。

// Search Tags.
const search_tags = ['CEO', 'Steven']

// Contacts.
let contacts = [
  { fname: 'Steven', lname: 'Johnson', email: 'user@domain.com', position: 'CEO' },
  { fname: 'James', lname: 'Laurence', email: 'boss@domain.com', position: 'CFO' }
]

// Matches.
const matches = contacts.filter((contact) => search_tags.every((tag) => Object.values(contact).includes(tag)))

// Log.
console.log(matches)

【讨论】:

    【解决方案3】:

    ES6:

    function filterIt(arr, searchKeys) {
      return arr.filter(obj => Object.keys(obj).some(key => searchKeys.includes(obj[key])));
    }
    

    【讨论】:

      【解决方案4】:

      careful ()=>"Arrow functions" 即使在某些现代浏览器中,浏览器的兼容性也很弱......它不适用于所有 IE 版本、所有黑莓和所有 Opera Mini 手机版android Safari ,不幸的是,你不能 pollyfill 这个功能。

      所以我建议你使用Object.keys()map()

      var contacts = [
         { fname: 'Steve', lname: 'Johnson', email: 'user@domain.com', position: 'CEO' },
         { fname: 'James', lname: 'Laurence', email: 'boss@domain.com', position: 'CFO' },
         { fname: 'random', lname: 'random2', email: 'random@g.com', position: 'user' }],
      
      
        contacts_query = function( search_tags ){ 
        //### the result will be stored here :
        var resultArray = [];
      
        // your contact Lists are using Numbers as keys like a Database :
        // 1 {...} , 2 {...} , 3 {...} so we need to loop throw those numbers first :
        for( var i in contacts ){ var contactsTable =  contacts[ i ];
      
         //@ mapping the contacts tables using their keys .
           Object.keys( contactsTable ).map( function( keys ){
         
            for( var y in search_tags ) // now we deal with search tags
               if( search_tags[ y ] == contactsTable[ keys ] )
                   resultArray.push( contactsTable );
           });  
      
         } return resultArray }; 
      
      
        //### usage :
        var query = contacts_query(['James', 'random@g.com']);
      
        console.log( query );

      这将使您的每个联系人列表都包含您的 search_tags[] 中的一个或多个值

      你也可以在上一个函数中使用(Object.values):

        Object.values( contactsTable ).map( function( values ){ ...       
      

      然后使用匹配结果:

       if( search_tags[ y ] == values ) ....
      

      【讨论】:

        猜你喜欢
        • 2015-03-24
        • 2014-11-20
        • 1970-01-01
        • 2021-12-15
        • 2021-10-23
        • 2022-07-04
        • 2019-04-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多