原生JS | 当兔子遇到鸡

HTML5学堂-码匠:当兔子遇到鸡,会怎样呢?先别急,看个小视频~
视频内容

当兔子遇到鸡 —— 不要害怕和别人不一样,在这个世界上,你就是独一无二的自己!

不知道有多少程序在看到这个小视频的时候,想到的不是“复活节”彩蛋,而是“鸡兔同笼问题”……

如果你想到的是“鸡兔同笼”,那么恭喜你,至少你不是一个人……(表示看到兔子从蛋里钻出来的时候,竟然完全没有怀疑 )。

鸡兔同笼问题

鸡兔同笼-起源

“鸡兔同笼问题”是我国古算书《孙子算经》中著名的数学问题,其内容是:“今有雉(鸡)兔同笼,上有三十五头,下有九十四足。问雉兔各几何。”

前端实现鸡兔同笼的计算功能

功能特效:

如果你具有一定JS基础,不妨尝试书写一下或想一想,再看“功能实现”,涉及到的小细节知识可不少,特别是没有内容的对象({})的检测方法。

鸡兔同笼功能的基本实现

鸡兔计算的核心公式

兔子数量 = 脚数 / 2 - 头数;

鸡数量 = 头数 - 兔子数量。

Tips:当然,如果你考虑用for循环,从1只兔子到N只兔子,一个一个尝试组合,也并非不可,但是循环匹配的方法计算效率实在是太低了,并不推荐。另外,关于公式的“推导”过程,可详见下图:

核心功能函数

function caculate(head, foot) {

    var result = {};
    var rabbit = foot / 2 - head;
    var chicken = head - rabbit;
    if (rabbit * chicken > 0 && parseInt(rabbit) == rabbit) {
        result = {
            'rabbit' : rabbit,
            'chicken' : chicken
        }
    };
    return result;
}

注意,此处增加了一个if判断。

rabbit * chicken > 0 用于保证至少有一只鸡、一只兔(能够防止负值和0的出现)

parseInt(rabbit) == rabbit 用于防止小数的产生。

无论是0、负数、还是小数,针对这个实例都是不合法的,因此需要进行控制。在有合法结果时返回一个对象,而在没有合法结果时返回一个空的对象 - {}

对象的检测

如何检测一个没有内容的对象呢?这个问题反而成为了解决“鸡兔同笼”功能需求的关键。

码匠:如何判断一个对象是没有内容的?

码匠好友:判断{}是否等于{}?

码匠:{} == {} 是不可能成立的,虽然两个对象都是没有内容的,但是这是两个对象。所以该方法不可行……

码匠好友:让{}与null相比较?{}不是没有内容吗?

码匠:虽然{}对象当中没有内容,但是它并不等于null。所以该方法也是不可行的。

码匠好友:进行长度检测?

码匠:length属性可用于数组,但不能用于对象。

码匠好友:使用for-in循环进行枚举总可以了吧!(详见如下检测案例1)

码匠:枚举的确能够实现,但是太过繁琐,可以其他一些方法进行实现。(详见如下检测案例2、3)

检测案例1 - 利用for-in循环枚举

var obj = {};
function checkObj(obj) {
    for(var i in obj) {
        if(obj.hasOwnProperty(i)){
            return false; // 不为空对象

        }
    }

    return true; // 空对象,返回true

}
checkObj(obj);

相关说明:使用for-in循环进行枚举,对于没有内容的空对象({}),i值并不会被赋值,for-in中的内容也不会执行。

对于hasOwnProperty的检测,主要是让方法检测该属性是否是自身属性,而非原型链上(继承而来)的属性。

类似方法:使用Object.keys(obj);

Object.keys(obj); 该方法类似于枚举,但是,是直接调用Object的keys方法,方法的返回值为 —— 所有可枚举属性的字符串数组。如果当前对象为空({}),则返回一个空数组。

var obj = {};
var checkResult = Object.keys(obj);
console.log(checkResult.length);

检测案例2 - 利用JSON.stringify方法

var obj = {};
console.log(JSON.stringify(obj) == '{}')

JSON.stringify()方法,用于将JSON对象转换为字符串,当将对象转换为字符串之后,自然就可以和另一个字符串相比较了~~~

在本案例中,HTML5学堂(码匠)选用的是该种方法。

第3方法:getOwnPropertyNames

Object.getOwnPropertyNames()方法,返回对象中,除了原型属性之外的所有属性(包括不可枚举属性),返回的内容为数组,如果该对象没有属性,则返回空数组。

由于该方法返回值为一个数组,因此可以通过length属性,进行判断,如果length长度为0,则代表该对象为空。

var obj = {};
var checkResult = Object.getOwnPropertyNames(obj);
console.log(checkResult.length);

完整功能代码

结构代码

行为代码

涉及到的细节知识

字符串转换为数字

通过input获取到的值,类型为字符串,需要优先转换为数字,再进行操作,在本案例中HTML5学堂(码匠)选用的是Number方法。

NaN的基本检测

当用户在input中输入非数字或不合法数字时,会通过上面的Number方法转换为NaN。

当出现NaN时,则需要给用户给予反馈,而不是继续进行运算,因此需要进行NaN进行检测。

NaN检测的方法很简单,让其与自身相比较,如果自己和自己不相等,那么,该值为NaN

整数检测

在鸡兔同笼计算当中,有可能用户输入的内容是合法数字,也是合法整数,但是有可能在运算之后变成小数。这种情况,是由于用户输入了不成立的数字组合。例如:头3只,脚7只。

对于此类问题,需要借助数字取整来检测,此处HTML5学堂(码匠)使用的是parseInt方法,针对兔子的数字取整,然后再跟原始的兔子数字比较,如果相同,则原始数字为整数。

没有内容的对象检测

在上面已经进行了详细讲解,在此罗列一下检测没有内容的对象的方法:

● JSON.stringify(obj);

● Object.keys(obj);

● Object.getOwnPropertyNames(obj);

查看效果实例:https://codepen.io/majiang/pen/oWoGmz

原文发布于微信公众号 - HTML5学堂(h5course-com)

原文发表时间:2017-05-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏灯塔大数据

技术 | Python从零开始系列连载(二)

上一期学的upyter相信大家都已经会用了,我们这一期就可以愉快地学习写代码啦! Python的基本数据类型 数据类型在数据结构中的定义是一个值的集合以及定义在...

3426
来自专栏Dawnzhang的开发者手册

数据结构与算法学习笔记之 从0编号的数组

数组看似简单,但掌握精髓的却没有多少;他既是编程语言中的数据类型,又是最基础的数据结构;

963
来自专栏一英里广度一英寸深度的学习

线性排序算法-堆排序 (2)

在学数据结构的时候,链表、堆栈、树三种数据结构印象最深刻。当时理解有误区,堆栈被当成一种结构,可能因为堆栈有同样的特性——只关心堆顶或栈顶的元素。

803
来自专栏漫漫深度学习路

tensorflow:上下文管理器 与 name_scope, variable_scope

tensorflow的上下文管理器,详解name_scope和variable_scope with block 与上下文管理器 上下文管理器:意思就是,在这个...

2646
来自专栏数据小魔方

左手用R右手Python系列之——数据框与apply向量运算

R语言与Python中的apply函数都有着丰富的应用场景,恰到好处的使用apply函数,可以避免在很多场景下书写冗余的代码,这不仅能提高代码可读性,而且提高代...

44411
来自专栏彭湖湾的编程世界

【javascript】详解变量,值,类型和宿主对象

JS数据类型 JS类型分类 ? 讲到类型, 首先要说的当然是JS的类型分类, 对于这一点,《javascript高级语言程序设计》和《你不知道的javasvri...

1806
来自专栏信数据得永生

JavaScript 编程精解 中文第三版 五、高阶函数

28010
来自专栏C语言及其他语言

[每日一题]统计字符

这也是一道字符串类型中比较常规的题(但含自定义函数哦),但前提得知道一个函数哦,就会简单很多!!! 如果你不知道,写完这题你就知道了哦!!! 题目描述 编写一...

3268
来自专栏王大锤

swift之函数式编程

最近初学swift,和OC比,发现语言更现代,也有了更多的特性。如何写好swift代码,也许,熟练使用新特性写出更优秀的代码,就是答案。今天先从大的方向谈谈sw...

442
来自专栏恰同学骚年

正则表达式30分钟入门教程--deerchao

原文地址:http://www.cnblogs.com/deerchao/archive/2006/08/24/zhengzhe30fengzhongjiaoc...

1074

扫码关注云+社区