【问题标题】:Apply every function to forEach javascript将每个函数应用于 forEach javascript
【发布时间】:2021-02-03 10:13:31
【问题描述】:

那是我的对象标签:

tabs: [
    {
      visible: true,
      title: 'tab 0',
      products: [{id:1, send: true, delivered: true}, {id:1, send: true, delivered: true}],
    },
    {
      visible: true,
      title: 'tab 1',
      products: [{id:11, send: true, delivered: false}, {id:21, send: true, delivered: true}],
    }
  ],

const allDerivered = (product) => product.delivered;
options.tabs.forEach(function (projectProducts){
   if (projectProducts.products.every(allDerivered)){
       statusTabs = 'DELIVERED';
  }
 });

就像第一个产品选项卡都是派生的,它不会遍历所有选项卡对象。如何将 allDerived 函数应用于所有选项卡?

【问题讨论】:

  • 你为什么有async?您显示的代码中没有任何异步发生。
  • 因为我只复制了一部分代码,它会做其他事情。我如何应用每个函数 forEach?
  • 正在为所有标签调用allDelivered。更具体地说,您为所有选项卡和每个选项卡中的至少一个产品调用它。如果它为产品返回false,您将不会在该选项卡中为以后的产品调用该函数,因为您使用了every,当回调返回一个虚假值时它会停止。但我应该注意,一旦您设置了一次statusTabs = 'DELIVERED',为每个选项卡调用它似乎没有任何意义,因为此时代码不会做任何事情。
  • 正在应用所有这些功能。但是,我不清楚你期望发生什么。计算机将完全按照您的要求执行,但是,这似乎不是您想要它执行的操作。现在,它只是将值“DELIVERED”分配给一些(希望是)名为statusTabs 的变量。请描述应该发生的情况,以便我们为您提供帮助。

标签: javascript arrays express foreach


【解决方案1】:

如果所有标签中的所有产品已交付,我猜你想将statusTabs设置为"DELIVERED",而不是如果 任何标签中的任何产品均未交付。如果是这样,您可以通过几种方式做到这一点。

您可以使用嵌套的every 调用:

if (options.tabs.every(({products}) => products.every(({delivered}) => delivered)) {
    statusTabs = "DELIVERED";
}

或带有标签和定向break 的嵌套循环:

let allDelivered = true;
outer: for (const {products} of options.tabs) {
    for (const {delivered} of products) {
        if (!delivered) {
            allDelivered = false;
            break outer;
        }
    }
}
if (allDelivered) {
    statusTabs = "DELIVERED";
}

如果您在 false 情况下也分配给 statusTabs,那就不那么麻烦了:

statusTabs = "DELIVERED";
outer: for (const {products} of options.tabs) {
    for (const {delivered} of products) {
        if (!delivered) {
            statusTabs = "UNDELIVERED";
            break outer;
        }
    }
}

我将对剩下的答案做出这个假设。

我没有在上面使用allDelivered,因为名称与函数的作用不匹配(它只检查一个产品是否已交付,而不是全部交付)并且因为该函数所做的只是对属性值的一次检查,这与内联完成的一样清晰。但是,如果您想要一个可重复使用的函数来执行该检查,您可以拥有一个:

const isDelivered = ({delivered}) => delivered;

那么上面的两个代码块将是:

if (options.tabs.every(({products}) => products.every(isDelivered)) {
    statusTabs = "DELIVERED";
}

或带有标签和定向break 的嵌套循环:

statusTabs = "DELIVERED";
outer: for (const {products} of options.tabs) {
    for (const product of products) {
        if (isDelivered(product)) {
            statusTabs = "UNDELIVERED";
            break outer;
        }
    }
}

您可以更进一步,为标签添加allProductsDelivered 函数:

const allProductsDelivered = ({products}) => products.every(isDelivered);

那么嵌套的every 将是:

if (options.tabs.every(allProductsDelivered)) {
    statusTabs = "DELIVERED";
}

循环版本是:

statusTabs = "DELIVERED";
for (const {products} of options.tabs) {
    if (!allProductsDelivered(tab)) {
        statusTabs = "UNDELIVERED";
        break;
    }
}

【讨论】:

  • 我喜欢 break outer 的嵌套循环,尤其是当 OP 确实执行任何异步操作时。
  • @Keith - 好点,OP 确实提到了一些 async 的东西......
  • @Keith - 请注意,嵌套循环版本最初是错误的。 :-D 我现在已经修好了。
【解决方案2】:

我猜你想要这样的东西:

const tabs = [{
    visible: true,
    title: 'tab 0',
    products: [{
      id: 1,
      send: true,
      delivered: true
    }, {
      id: 1,
      send: true,
      delivered: true
    }],
  },
  {
    visible: true,
    title: 'tab 1',
    products: [{
      id: 11,
      send: true,
      delivered: false
    }, {
      id: 21,
      send: true,
      delivered: true
    }],
  }
];

const isNotDelivered = (product) => product.delivered == false;

tabs.forEach(tab => {
  const areAllProductsDelivered = !tab.products.find(isNotDelivered);
  if (areAllProductsDelivered) {
    console.log(`${tab.title} is completely delivered`);
  } else {
    console.log(`${tab.title} is NOT completely delivered`);
  }
});

【讨论】:

    猜你喜欢
    • 2015-02-27
    • 2012-03-07
    • 2018-02-26
    • 1970-01-01
    • 2019-03-01
    • 1970-01-01
    • 2014-03-25
    • 2018-07-16
    • 2013-02-02
    相关资源
    最近更新 更多