在 _.filter 中使用 _.every
Using _.every inside _.filter
我正在研究 javascript-koans,这是 AboutApplyingWhatWeHaveLearnt.js 的第一个挑战。目标是编写函数式代码——给出命令式答案——删除没有蘑菇和坚果的产品,将它们推入一个新数组,并获取该数组的长度。这是我正在使用的数据集:
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 }
];
这是挑战的指导:
solve using filter() & all() / any()
我坚持使用每个内部过滤器(推动、长度等不是问题)。我能够过滤掉没有坚果的条目,并使用每个(所有的别名),使用每个产品的索引搜索每个产品的成分数组,如果数组包含 "mushrooms",则返回 true/false。但是,我想使用过滤器的每个内部,所以我不必使用循环。这是我想出的,但它没有返回任何条目:
_.filter(products, function(product) {
if(_.every(product.ingredients, function(ingredient) {ingredient !== "mushrooms"})){
return product;
}
})
我想做的事情有可能吗?非常感谢任何指导。
你的问题是 _.every
函数中没有 "return"。
看来这应该可以解决您提供的代码段的问题:
_.filter(products, function(product) {
return product.ingredients.indexOf('mushrooms') === -1;
});
就整个问题而言,试试这个:
_.filter(products, function(product) {
return _.every(product.ingredients, function(ingredient) {
if (/nut|mushroom/.test(ingredient) {
altArray.push(ingredient);
return false;
}
return true;
});
});
假设您想要创建一个删除了元素的数组版本,以及另一个删除了元素的数组,我们可以定义一个 partition
函数,它通常基于过滤函数来执行此操作。参见 。
function partition(arr, filter) {
var fail = [];
var pass = arr.filter((e, i, a) => {
if (filter(e, i, a)) return true;
fail.push(e);
});
return [pass, fail];
}
对于过滤功能,其实并不需要every
。只需检查每个元素的成分列表不包含蘑菇,并且 containsNuts
属性 是错误的:
function filter(product) {
return !product.containsNuts && !product.ingredients.contains('mushrooms');
}
现在你可以做
partition(products, filter)
这将 return 一个数组,其第一个元素是传递元素的数组(没有蘑菇等),第二个元素是失败元素的数组。
我正在研究 javascript-koans,这是 AboutApplyingWhatWeHaveLearnt.js 的第一个挑战。目标是编写函数式代码——给出命令式答案——删除没有蘑菇和坚果的产品,将它们推入一个新数组,并获取该数组的长度。这是我正在使用的数据集:
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 }
];
这是挑战的指导:
solve using filter() & all() / any()
我坚持使用每个内部过滤器(推动、长度等不是问题)。我能够过滤掉没有坚果的条目,并使用每个(所有的别名),使用每个产品的索引搜索每个产品的成分数组,如果数组包含 "mushrooms",则返回 true/false。但是,我想使用过滤器的每个内部,所以我不必使用循环。这是我想出的,但它没有返回任何条目:
_.filter(products, function(product) {
if(_.every(product.ingredients, function(ingredient) {ingredient !== "mushrooms"})){
return product;
}
})
我想做的事情有可能吗?非常感谢任何指导。
你的问题是 _.every
函数中没有 "return"。
看来这应该可以解决您提供的代码段的问题:
_.filter(products, function(product) {
return product.ingredients.indexOf('mushrooms') === -1;
});
就整个问题而言,试试这个:
_.filter(products, function(product) {
return _.every(product.ingredients, function(ingredient) {
if (/nut|mushroom/.test(ingredient) {
altArray.push(ingredient);
return false;
}
return true;
});
});
假设您想要创建一个删除了元素的数组版本,以及另一个删除了元素的数组,我们可以定义一个 partition
函数,它通常基于过滤函数来执行此操作。参见
function partition(arr, filter) {
var fail = [];
var pass = arr.filter((e, i, a) => {
if (filter(e, i, a)) return true;
fail.push(e);
});
return [pass, fail];
}
对于过滤功能,其实并不需要every
。只需检查每个元素的成分列表不包含蘑菇,并且 containsNuts
属性 是错误的:
function filter(product) {
return !product.containsNuts && !product.ingredients.contains('mushrooms');
}
现在你可以做
partition(products, filter)
这将 return 一个数组,其第一个元素是传递元素的数组(没有蘑菇等),第二个元素是失败元素的数组。