如何重写下面的函数,使其不会't用于循环

How to rewrite the following function so it doesn't use for loops?

本文关键字:循环 用于 重写 何重写 函数      更新时间:2023-09-26

以下函数获取一个对象,循环遍历每个值,如果对象或其子对象具有空或未定义的属性web,则返回false。否则返回true:

hasNoCategories (object) {
  for (let key in object) {
    const value = object[key]
    for (let i = 0; i < value.length; i++) {
      const item = value[i]
      if (item.web !== undefined && item.web !== '') return false
    }
    if (key === 'web' && value !== '') {
      return false
    }
  }
  return true
},

示例输入:

{
  "livingroom": [],
  "garage": [],
  "outdoors": [],
  "other": [],
  "id": "ZI4hteKxgr",
  "name": "Cuiti",
  "description": "",
  "user": "",
  "date": "2016/5/13",
}

如何在不使用for循环的情况下重写此函数?

我不能100%确定您希望代码做什么,因为您现有的代码和您的描述不同。

您的描述是,该函数检查object.web或任何object.XXX.web是否未定义。但是,您的代码假设所有成员都是数组,并检查object.webobject.XXX[YYY].web是否未定义。(请注意,它也没有正确执行并访问.length,即使有问题的成员可能未定义。)

由于我不确定其中哪一个是正确的,我提供了两个答案。

根据文本描述的功能:

function hasNoCategories(object) {
    if(!object.web) return false;
    return Object.keys(object).every(function(key) {
        if(typeof object[key] !== 'object') return true;
        return !!object[key].web;
    });
}

根据现有代码的功能:(但固定了length属性访问)

function hasNoCategories(object) {
    if(!object.web) return false;
    return Object.keys(object).every(function(key) {
        if(!Array.isArray(object[key])) return true;
        return object[key].every(function(el) {
            if(typeof object[key] !== 'object') return true;
            return !!el.web;
        });
    });
}

要了解这是如何工作的,请查看关于Object.keys(它返回一个包含对象中所有键名称的数组)和Array.prototype.every(它为数组中的每个元素运行回调函数,只有当回调为每个元素返回true时才返回true)的文档。

注意,我假设您的"空或未定义"应该拒绝所有类型的错误值,包括null和数字(而不是字符串)零。如果不是,那么像if(!something)return !!something这样的所有检查将需要分别更改为if(typeof something === "undefined" || something === '')return typeof something !== "undefined" && something !== ''

防止挑剔的旁注:当然还有循环在进行。但有人特别要求"没有for循环",而且这段代码中没有for

我想这就是您想要的:

var hasNoCategories = function(object) {
    if (!object.web) {
        return false;
    }
    for (let key in object) {
        var value = object[key];
        if (!value.web) {
            return false;
        }
    }
    return true;
};

我去掉了1个循环。但这不能在没有循环的情况下完成,因为你必须循环所有的孩子。你可以将这个循环隐藏在另一个函数中,但你无法摆脱它。

如果你真的不想使用循环(我不知道为什么),你的选择之一是序列化对象并用短语表示单词"web"的字符串。

var s = JSON.stringify(object);
var webIndex = s.indexOf('web');

现在围绕这个索引执行一些检查,以确定它的值是'undefined'还是''。请记住,单词"web"也可以作为另一个属性名称的一部分进行匹配。所以,你也需要把这种可能性包括在你的支票中。