简体   繁体   English

使用underscore.js过滤数组

[英]Filtering array with underscore.js

I am trying to filter some objects in my attempt to understand JS better and I'm using underscore.js 我试图过滤一些对象,试图更好地理解JS,我正在使用underscore.js

I come from a C# background and am used to LINQ however underscore is not quite the same. 我来自C#背景并习惯LINQ但是下划线并不完全相同。

Can you help me filter out this array based on the defined test, the issue I'm having is the array property on the array. 你能帮我根据定义的测试过滤掉这个数组,我遇到的问题是数组上的数组属性。 The Where operator is diffeernt to C# which is what I'd normally use to filter items. Where运算符与C#不同,这是我通常用来过滤项目的东西。

products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];

it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      //This works but was hoping I could do the mushroom check as well in the same line
      var noNuts = _(products).filter(function (x) { return !x.containsNuts;});

      var noMushrooms = _(noNuts).reject(function(x){ return !_(x.ingredients).any(function(y){return y === "mushrooms";});});


      console.log(noMushrooms);

      var count = productsICanEat.length;
      expect(productsICanEat.length).toBe(count);
  });

You just need to remove the ! 你只需要删除! from the reject callback so that it look like this: reject回调,使它看起来像这样:

var noMushrooms = _(noNuts).reject(function(x){ 
    return _(x.ingredients).any(function(y){return y === "mushrooms";});
});

Otherwise you're rejecting the ones that don't contain mushrooms instead of those that do. 否则,你会拒绝含有蘑菇,而不是那些做的人。

A more concise way to accomplish this would be with underscore's chain() function: 更简洁的方法是使用下划线的chain()函数:

var noMushrooms = _(products).chain()
    .filter(function (x) { 
        return !x.containsNuts;})
    .reject(function(x){ 
        return _(x.ingredients).any(function(y){
            return y === "mushrooms";
        });
    })
    .value();

I managed to get my solution all wrapped up into one filter call so thought I'd post it: 我设法让我的解决方案全部包含在一个过滤器调用中,所以我想发布它:

products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];

 it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      productsICanEat = _(products).filter(function (x) { return !x.containsNuts && !_(x.ingredients).any(function(y){return y === "mushrooms";});});


      expect(productsICanEat.length).toBe(1);
  });

This will give the desired result 这将给出期望的结果

var no_nuts = _.filter(products,function(item) {
         return !item.containsNuts;
       });

var no_mushroom = _.reject(no_nuts,function(item) {
        return _.any(item.ingredients,function(item1) {
            return item1 === "mushrooms"
        }); 
     });

console.log(no_mushroom);

reject() does the opposite of filter() , and any() is equivalent to some method of arrays which returns true when any of the element in the array when passed through a callback returns true. reject()filter()相反,而any()等效于某些数组方法,当数组中任何元素通过回调传递时返回true。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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