通过搜索嵌套对象属性来过滤对象数组

时间:2017-08-08 17:57:38

标签: javascript arrays object filter

我想通过比较嵌套属性和搜索词来过滤一系列对象。

例如:

 var array = [
      {category: 'Business'
       users: [
                {name: 'Sally'
                 tags: [{tag: 'accounting'}, {tag: 'marketing'},...]
                },
                {name: 'Bob'
                 tags: [{tag: 'sales'}, {tag: 'accounting'},...]
                }...
              ]
       },
       {category: 'Heritage'
        users: [
                 {name: 'Linda'
                  tags: [{tag: 'Italy'}, {tag: 'Macedonia'},...]
                 },
                 {name: 'George'
                  tags: [{tag: 'South Africa'}, {tag: 'Chile'},...]
                 },...
               ]
       },...
    [

基本上我想通过搜索术语来过滤对象的基础数组,这些搜索术语包含嵌套对象2数组中的标记属性字符串中的字符。

所以搜索市场'会导致

[
  {category: 'Business'
   users: [
            {name: 'Sally'
             tags: [{tag: 'accounting'}, {tag: 'marketing'},...]
            },
            {name: 'Bob'
             tags: [{tag: 'sales'}, {tag: 'accounting'},...]
            }...
          ]
   }
]

谢谢。

6 个答案:

答案 0 :(得分:5)

您可以使用Array#filter使用Array#some查看嵌套数组。

如果在嵌套数组中找到标记,则迭代停止,结果将返回到过滤器回调。



var array = [{ category: 'Business', users: [{ name: 'Sally', tags: [{ tag: 'accounting' }, { tag: 'marketing' }] }, { name: 'Bob', tags: [{ tag: 'sales' }, { tag: 'accounting' }] }] }, { category: 'Heritage', users: [{ name: 'Linda', tags: [{ tag: 'Italy' }, { tag: 'Macedonia' }] }, { name: 'George', tags: [{ tag: 'South Africa' }, { tag: 'Chile' }] }] }],
    tag = 'marketing',
    result = array.filter(a => a.users.some(u => u.tags.some(t => t.tag.includes(tag))));

console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }




答案 1 :(得分:1)

试试这个:

right: -30px

所以:

function search(term){
return
    Array.filter(array,function(item){
       return JSON.stringify(obj).indexOf(term)!=-1;
    });
}

我希望对你有所帮助:)。

答案 2 :(得分:1)

使用Array.prototype.some()函数的解决方案:



var arr = [{ category: 'Business', users: [{ name: 'Sally', tags: [{ tag: 'accounting' }, { tag: 'marketing' }] }, { name: 'Bob', tags: [{ tag: 'sales' }, { tag: 'accounting' }] }] }, { category: 'Heritage', users: [{ name: 'Linda', tags: [{ tag: 'Italy' }, { tag: 'Macedonia' }] }, { name: 'George', tags: [{ tag: 'South Africa' }, { tag: 'Chile' }] }] }], 
    search_key = 'market',
    result = [];
    
arr.forEach(function(o){
    if (o.users.some(function(v){
        return v.tags.some(function(i){ return i.tag.indexOf(search_key) !== -1; });
    })) {
        result.push(o);
    }
});

console.log(result);




答案 3 :(得分:0)

您可以像这样使用array.filter

function getFiltered(val) {
     return array.filter(category == val);
}

此函数将返回一个新的数组实例,仅使用您作为category参数传递的val个键。

答案 4 :(得分:0)

注意:我采用类似快捷方式的方法,主要是为问题提供不同的视角。

您可以创建array属性的json字符串,并在其中进行搜索,而不是深入搜索主users下的属性和数组。所以我创建了一个新属性usersString,它临时存储了users属性的值的JSON字符串。

item.usersString = JSON.stringify(item.users);

现在,这不是一个完美的实现,但它几乎总是有效。此外,如果您将此属性存储在浏览器中(不将其存储回数据库),并且每次用户搜索时都使用它来快速搜索,我认为深度搜索整个数组会更有效。



var array = [{
    category: 'Business',
    users: [{
        name: 'Sally',
        tags: [{
          tag: 'accounting'
        }, {
          tag: 'marketing'
        }]
      },
      {
        name: 'Bob',
        tags: [{
          tag: 'sales'
        }, {
          tag: 'accounting'
        }]
      }
    ]
  },
  {
    category: 'Heritage',
    users: [{
        name: 'Linda',
        tags: [{
          tag: 'Italy'
        }, {
          tag: 'Macedonia'
        }]
      },
      {
        name: 'George',
        tags: [{
          tag: 'South Africa'
        }, {
          tag: 'Chile'
        }]
      }
    ]
  }
];

var key = "market";

// Convert the users property into a string - so that it works as a quick search target.
array.forEach(function(item) {
  item.usersString = JSON.stringify(item.users);
});


var filteredItems = array.filter(function(item) {
  return item.usersString.toLowerCase().indexOf(key.toLowerCase()) >= 0;
});

// Delete the usersString property - if required.
filteredItems.forEach(function(item) {
  item.usersString = undefined;
  // Or,
  // delete item.usersString;
})

console.log(filteredItems);




答案 5 :(得分:0)

concatAllconcatMap定义取自http://reactivex.io/learnrx/

Array.prototype.concatAll = function() {
    var results = [];
    this.forEach(function(subArray) {
        results.push.apply(results, subArray);
    });

    return results;
};

Array.prototype.concatMap = function(projectionFunctionThatReturnsArray) {
    return this.
        map(function(item) {
            return projectionFunctionThatReturnsArray(item);
        }).
        // apply the concatAll function to flatten the two-dimensional array
        concatAll();
};

function filterByTags(keyword) {
  return array.filter(function (item) {
    var allTags = item.users.concatMap(function (user) {
      return user.tags.map(function (tag) {
        return tag.tag;
      });
    });

    return allTags.some(function (tag) {
      return tag.indexOf(keyword) > -1;
    });
  });
}

console.log(filterByTags('market'));

当然,您可以内联allTags变量以获得更简洁。

应用于初始数组的filter将返回包含其标签包含所提供关键字的用户的所有项目。策略是构建用户标签的扁平版本,并在其上应用some