原生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 条评论
登录 后参与评论

相关文章

来自专栏吴裕超

js中三目运算符和&& || 符的个人浅见

这两天看到别人写的代码,感觉很牛逼,如下,大神请忽视 $(".lgn").on("click", function() { var a = {}...

3387
来自专栏java一日一条

10个惊艳的Swift单行代码

几年前,一篇表述“10个Scala函数式单行代码”的文章非常受欢迎,并且随后立马出现了其他的语言版本,例如Haskell版本,Ruby版本,Groovy版本,C...

242
来自专栏小灰灰

Java 一步一步实现高逼格的字符串替换工具(一)

Java 一步一步实现高逼格的字符串替换工具(一) 如果你有一段模板, 需要用某些数据替换其中的关键信息,怎么做 "hello, {user}, welc...

2527
来自专栏陈树义

UML类图及类图的几种常见关系

1、类的表示 类通常由三部分组成,即:类名、属性、方法。UML表示类图如图所示: ? 2、接口的表示 在UML中,接口使用一个带有名称的小圆圈来进行表示: ? ...

2644
来自专栏wOw的Android小站

[设计模式]之十:组合模式

将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

81
来自专栏猿人谷

怎样写解释器

解释器是比较深入的内容。虽然我试图从最基本的原理讲起,尽量让这篇文章不依赖于其它的知识,但是这篇教程并不是针对函数式编程的入门,所以我假设你已经学会了最基本的 ...

1827
来自专栏小文博客

蓝桥杯 C语言省赛 习题1 奖券数目

1112
来自专栏专知

【专知-关关的刷题日记15】Leetcode 27. Remove Element 方法1、2、3

题目 Given an array and a value, remove all instances of that value in place and r...

3267
来自专栏nummy

ECMAScript 6 特性ECMAScript 6 特性

ECMAScript 6,也被称做ECMAScript 2015,是ECMAScript标准的下一个版本。这个标准预计将于2015年6月被正式批准。ES6是这门...

491
来自专栏斑斓

引入Option优雅地保证健壮性

REA的Ken Scambler在其演讲《2 Year of Real World FP at REA》中,总结了选择函数式编程的三个原因:Modularity...

3325

扫描关注云+社区