如何重写以下函数,以便它不用于for循环?

时间:2016-05-18 06:40:51

标签: javascript

以下函数接受一个对象,循环遍历每个值,如果对象或其子对象具有空或未定义属性false,则返回web。否则,它返回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循环的情况下重写此函数?

3 个答案:

答案 0 :(得分:1)

我不能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

答案 1 :(得分:-2)

我认为这就是你要找的东西:

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个循环。但是没有循环就无法做到这一点,因为你必须遍历所有孩子。你可以将这个循环隐藏在另一个函数中,但是你无法摆脱它。

答案 2 :(得分:-3)

如果你真的不想使用循环(我不知道为什么),你的一个选择是序列化对象和短语“web”这个词的字符串。

var s = JSON.stringify(object);

var webIndex = s.indexOf('web');

现在围绕此索引执行一些检查,以确定其值是'undefined'还是''。请记住,“web”这个词也可以作为另一个属性名称的一部分。因此,您需要将这种可能性包含在您的支票中。