【问题标题】:Find all Objects in a Collection with at least one matching property查找集合中具有至少一个匹配属性的所有对象
【发布时间】:2016-10-14 14:10:58
【问题描述】:

我有一个包含对象的数组。总之

    Array =[  
    {id = 1, products='1,2'} //products consist of String with Products Seperates by','
    {id = 2, products='1'}  
    {id = 3, products='3'}  
    {id = 4, products='1,2,3'}
    {id = 5, products='2,3'}
    ...  
    ]
SelectedProd = ['2,3']// consists a String as well seperated by ','

这些都显示在一个表格中。我现在正在编写一个过滤器以仅显示通过 MultipleSelect 选择的过滤器。
因此,我想过滤所有对象,其中至少一个产品位于 products
所以我的过滤器正在获取对象和选定的产品

.filter('filterByProd', () => {
          return (objects,prod) => {
            var filtered = [];
            /*
FIlter Array
*/
            return filtered;
          };
        });

如果用户选择 Product = '2,3',它将返回带有 id=1/3/4/5.. 的对象
同样清楚的是,如果没有选择全部返回。 如果可能,请使用 lodash,但也接受其他解决方案。
我遇到的问题是函数只是在 lodash Docu 中列出,无法阅读我需要的每个人。
目前我被困在

.filter('filterByProd', () => {
  return (items,prod) => {
    var filtered = [];
    filtered = _.filter(items,['products',prod]);
    return filtered;
  };
});  

这只是给我与'2,3' 的完全匹配 -> 仅Object = id=5
我需要一些东西

filtered = findAllWhere(selectedProducts,iterateOverSendObjects(checkProductsOfObjects)+_.ifIsAtLeastOneOfSendProducts))  

【问题讨论】:

  • 为什么要为'2,3' 之类的产品提供一个字符串,而在您的问题中使用[2,3] 的数组更有意义?这将是一个简单的迭代它们的问题
  • 我从我的服务器上得到它。
  • 无论哪种方式,您都需要解析它。您可以在获取数据或尝试过滤时立即执行此操作

标签: angularjs underscore.js lodash angular-filters


【解决方案1】:

你可以使用 lodash 的交集方法得到你想要的结果。

var a = arr.filter(x => {
    return _.intersection(
             x.products.split(','), SelectedProd[0].split(',')
           ).length > 0;

这是一个有效的内联小提琴:

var arr = [  
    {id : 1, products:'1,2'}, 
    {id : 2, products:'1'},  
    {id: 3, products:'3'},  
    {id : 4, products:'1,2,3'},
    {id : 5, products:'2,3'}];

var SelectedProd = ['2,3'];

var a = arr.filter(x => {
    return _.intersection(
             x.products.split(','), SelectedProd[0].split(',')).length>0;
});

console.log(a);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.js"></script>

解释:

Lodash _.intersection 如果存在则返回两个数组的交集,否则返回 []。我们使用过滤器只过滤那些交集不为空的对象

【讨论】:

  • 我正在运行您的解决方案,谢谢。还有一个问题,如果没有选择,是否有类似 var a = arr.filter(....).if(selected===null) return arr;目前,我在过滤之前使用 if 进行简单检查。只是想知道我是否可以附上这样的东西? :)
【解决方案2】:

从服务器获取此对象后,修改它,方法是注入一个包含数组格式的 CSV 的新数组属性,或者用数组完全替换产品。在绑定之前,您的最终数组应如下所示:

[
{id = 1, products=[1,2]}, {id = 2, products=[1]} ... ]

如果有帮助请标记为答案

【讨论】:

  • 有没有不修改的解决方案?因为我在更多的功能中使用它而不仅仅是这个过滤器。它仍然不是一个解决方案,然后如何过滤我想要的对象?
  • 如果您的所有服务器响应对象都相似,您可以轻松创建一个简单的映射器模块来处理响应对象转换。关于您关于过滤的问题:您可以做的是在遍历您的对象数组的 foreach 循环中使用 indexOf JS 操作。如果 indexOf 操作为每个选定的产品返回非 -1 值,您可以将其添加到最终结果集中。这应该可以解决问题。
  • 不,它们大多都不同。这是这样来的,因为它是需要的。但是,如果您解释如何修改,那么我只能在过滤器中进行。并在那里进行过滤
  • @AkAk47 :过滤逻辑请参考我上面的评论,如果有帮助,标记为答案。
  • @AkAk47 :提个建议,使用映射层非常实用。最好不要在转换之前尝试将服务器端响应直接绑定到 UI。
【解决方案3】:

您可以使用Array.prototype.filter()Array.prototype.some()String.prototype.includes() 过滤项目以搜索字符串中的选定项目:

const findIemsByProducts = (items, selectedProd) => {
  const selected = selectedProd[0].split(','); // convert the selected products to array
  
  return items.filter((item) => // filter the items
    selected.some((productId) => // if at least one of the selected
      item.products.includes(productId) // is in the products string
    ));
}

var items = [  
  {id: 1, products: '1,2'},
  {id: 2, products: '1'},
  {id: 3, products: '3'},  
  {id: 4, products: '1,2,3'},
  {id: 5, products: '2,3'}
];

var SelectedProd = ['2,3'];

var results = findIemsByProducts(items, SelectedProd);

console.log(results);

角度过滤器将是:

.filter('filterByProd', () => (items, selectedProd) => {
  const selected = selectedProd[0].split(','); // convert the selected products to array

  return items.filter((item) => // filter the items
    selected.some((productId) => // if at least one of the selected
      item.products.includes(productId) // is in the products string
    ));
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-09
    • 2010-10-09
    • 1970-01-01
    • 2019-04-03
    • 2017-03-15
    • 1970-01-01
    • 1970-01-01
    • 2016-10-18
    相关资源
    最近更新 更多