normalizr

作者: woow_wu7 | 来源:发表于2018-06-19 23:56 被阅读13次

    安装

    yarn add normalizr
    
    cnpm install normalizr
    

    api

    • normailze
    • denormalize
    • schema

    实例

    import {normalize, schema} from 'normalizr';
    
    
    componentDidMount() {
            const date = {
                id: 1,
                name: 'wang',
                subject:[
                    {
                        id:11,
                        name:'语文',
                        score: [
                            {
                                id:111,
                                '期中': '80'
                            },
                            {
                                id:112,
                                '期末': '90'
                            }
                        ],
                    },
                    {
                        id: 12,
                        name: '数学',
                        score: [
                            {
                                id: 113,
                                '期中': '80'
                            },
                            {
                                id: 114,
                                '期末': '90'
                            }
                        ],
                    }
                ],
            };
    
            const scoreSchema = new schema.Entity('score');
            const newScore = [scoreSchema];
    
            const subjectSchema = new schema.Entity('subject', {
                score: newScore
            });
            const newSubject = [subjectSchema];
    
            const dataSchema = {
                subject: newSubject,
            };
            const newData = normalize(date, dataSchema)
            console.log(newData)
    
            
        }
    

    score被提出来,到entity中了, result中的subject是个数组索引

    denormalize

    denormalize(input, schema, entities)
    即是
    denormalize(result, schema, entities) // 第一个参数是normalize后得到结果中的
    result

    import { denormalize, schema } from 'normalizr';
    
    const user = new schema.Entity('users');
    
    const mySchema = { users: [ user ] }
    
    const entities = { users: { '1': { id: 1 }, '2': { id: 2 } } };
    
    const denormalizedData = denormalize({ users: [ 1, 2 ] }, mySchema, entities);
    
    
    
    结果:
    { 
      users: [
        { id: 1 },
        { id: 2 }
      ]
    }
    









    强制转换

    • Number()
    • String()
    • Boolean()

    Number()

    Number()函数可以将任意类型的值,转换成数值
    两种情况,参数是原始类型的值,和参数是对象(符合类型的值)

    • 原始类型的值
    Number()
    
    1. 数值转换后还是数值
    Number(123) //123
    
    2. 字符串如果可以解析为数值,则转换成数值
    Number('123') //123
    
    3. 字符串如果不可以被解析为数值,则返回 NaN  ----------------------(重要)
    Number('123abc') // NaN
    
    4. 空字符串 会被转换成 0  --------------------------------------(重要)
    Number('') // 0
    
    5. 布尔值 true转换成1    false转化成0 --------------------------(重要)
    Number(true) //1
    Number(false) //0
    
    6. undefined被转换成 NaN -------------------------------------(重要)
    Number(undefined) // NaN
    
    7. null被转换成0 ---------------------------------------------(重要)
    Number(null) //0
    
    
    总结:
    被转换成0的有:null false 空字符串
    被转换成NaN的有: undefined 和 不可以被转化成数值的字符串
    
    • 对象

    简单的规则是,Number方法的参数是对象时,将返回NaN,除非是包含单个数值的数组。

    • 参数是对象时,返回NaN
    • 特例:单个值得数组 返回数组中的单个值得 数值类型
    Number({a: 1}) // NaN
    Number([1, 2, 3]) // NaN
    Number([5]) // 5
    

    String()

    String(123) // "123"
    String('abc') // "abc"
    String(true) // "true"
    String(undefined) // "undefined"
    String(null) // "null"
    
    • String方法的参数如果是对象,返回一个类型字符串;
    • String方法的参数如果是数组,返回该数组的字符串形式。
    String({a: 1}) // "[object Object]"
    String([1, 2, 3]) // "1,2,3"
    

    自动类型转换

    三种情况js会自动转换数据类型

    • (1) 不同类型的数据相互运算
    • (2) 对非布尔类型的数据求布尔值
    • (3) 对非数值类型的值使用一元运算符

    自动转化的规则

    • 预期是什么类型的值,就调用该类型的转化函数。
    • 某个位子,预期是个字符串,就调用String函数。
    • 如果该位置,可以是字符串,也可以是数值,则默认转成数值。

    注意:自动转化具有不确定性,不易排错,一般在预期为数值,字符串,布尔值的地方使用 Number,String,Boolean就行显式转换

    自动转换为字符串

    • 字符串的自动转换,主要发生在字符串的 ( 加法运算 ) 时。
    • (字符串 + 非字符串 , 会将非字符串转换为字符串 )
    '5' + 1 // '51'
    '5' + true // "5true"
    '5' + false // "5false"
    '5' + {} // "5[object Object]"
    '5' + [] // "5"
    '5' + function (){} // "5function (){}"
    '5' + undefined // "5undefined"
    '5' + null // "5null"
    

    自动转化为数值

    除了( 加法运算符 )有可能将云算子转换成字符串,其他 ( 运算符 ) 都会把云算子转化成 数值

    • 注意:null转为数值时为0,而undefined转为数值时为NaN。
    • null 转为数值是 0
    • undefined 转为数字是 NaN






    2018/6/18复习 Date对象

    1. Date实例方法:有to,get,set三种类型
      get类: 获取 Date 对象的日期和时间
      set类: 设置 Date 对象的日期和时间
      to 类: 从 Date对象返回一个字符串,表示指定的时间

    getFullYear() 返回四位年份
    getMonth() 返回月份 ( 0表示1月 。。。。)
    getDate() 返回日期号数 ( 从1开始 )
    getDay() 返回星期几
    getHours() 返回小时数
    getMinutes() 返回分钟数
    getSeconds() 返回秒数

      componentDidMount() {
        const date = new Date();
        const year = date.getFullYear();
        const month = date.getMonth();
        const datex = date.getDate();
        const day = date.getDay();
        const hoursx = date.getHours();
        const minutesx = date.getMinutes();
        const secondsx = date.getSeconds();
        console.log(year, month + 1, datex, day, hoursx, minutesx, secondsx)
    }
    
    // 2018 6 18 1 11 11 21
    
    1. 表达式
      表达式是 一个为了得到返回值的计算。
      凡是预期为值的地方,都可以使用表达式。
      表达式一定会返回一个值。
    2. 语句
      语句以分号结尾。
      一个分号就表示语句的结束。
      多个语句可以写在一行内。
    3. 变量
      变量是对值的具名引用。

    prop-types库

    import React, { Component } from 'react';
    import PropTypes from 'prop-types';   // 引入prop-types库
    
    
    
    class newc extends Component {
    
      static propTypes = {             // 定义一个静态属性proptypes
          name: PropTypes.string,      // 加 static 关键词定义静态属性是新写法,以前是类型.静态属性名
      }
      render() {
        return (
          <div className="newc">
           测试prop-types
           <div>{this.props.name}</div>
          </div>
        );
      }
    }
    
    export default newc;
    
    

    RegExp对象 复习

    正则表达式 ( regular expression )
    regular : 是正规的,规则的意思
    expression : 是表达的意思

    (1) 新建正则表达式有两种方法

    • 一种是使用字面量,以斜杠开始和结束 ------------------- 编译时新建
      如: let regularExprssion = /abc/;
    • 一种是使用 RegExp 构造函数 ------------------------------- 运行时新建
      RegExp构造函数,可以接受第二个参数,表示修饰符
      如: let regularExpression = new RegExp('abc');
    var regex = new RegExp('xyz', 'i');
    // 等价于
    var regex = /xyz/i;
    
    • 在实际运用中,多采用字面量方式新建正则表达式,效率更高,也更直观。效率高是因为字面量方式在编译阶段就会新建,而 RegExp构造函数方法在运行时才会新建。

    (2) 实例属性

    正则对象的实例属性分为两类:

    • 一类是和修饰符相关,返回一个布尔值,表示对应的修饰符是否设置
    RegExp.prototype.ignoreCase :  返回boolean,表示是否设置了 i 修饰符。   -- 忽视大小写
    
    RegExp.prototype.global :      返回boolean,表示是否设置了 g 修饰符。   -- 全局模式
    
    RegExp.prototype.multiline:   返回boolean,表示是否设置了 m 修饰符。    -- 多线
    
    • 另一类是与修饰符无关的属性
    RegExp.prototype.lastIndex:返回一个数值,表示下一次开始搜索的位置。
    该属性可读写,但是只在进行连续搜索时有意义
    
    
    RegExp.prototype.source:返回正则表达式的字符串形式(不包括反斜杠)  !!!
    该属性只读。
    

    例子:

        let regexp = /abc/igm;
        const ignoreCase = regexp.ignoreCase;
        const global = regexp.global;
        const multiline = regexp.multiline;
        const lastIndex = regexp.lastIndex;  // 下一次开始搜索的位置。
        const source = regexp.source;    // 返回正则表达式的字符串形式,不包括反斜杠。 source属性
    
        console.log(ignoreCase, global, multiline, lastIndex, source)
    
    // true true true 0 "abc"
    

    (3) 实例方法

    (1) RegExp.prototype.test() ----- 返回布尔值,表示是否匹配

    正则实例的test()方法,返回一个布尔值,表示当前模式是否匹配参数字符串

    const one = /name/.test('my name is xxxxx')   // test()方法:当前模式是否匹配参数字符串
    console.log(one)
    // true
    

    带有 g 修饰符时,可以通过 lastIndex 属性, 指定开始搜索的位置

    • lastIndex属性只对同一个正则表达式有效
      const one = /name/g;     --------- const one = new RegExp('name', 'g'); 相等
      one.lastIndex = 4;
      one.test('正则带有g修饰符时,可以用lastIndex属性指定开始搜索的位置,name is xxx');
      // true
    
      one.lastIndex = 400;
      // false
    

    如果正则模式是一个空字符串,则匹配所有字符串。

    new RegExp('').test('abc')
    // true
    

    (2) RegExp.prototype.exec()

    ---------------------------- 返回数组,匹配成功的子字符串。

    如果正则表达式包含圆括号(组匹配),返回的数组会包括多个成员,第一个成员是整个匹配成功的结果,后面的成员是圆括号匹配成功的组。
    即第二个成员对应第一个括号,第三个成员对应第二个括号,以此类推。整个数组的length属性等于组匹配的数量再加1。

    ---------------------------- 没有匹配成功,返回null

    正则实例对象的exec方法,用来返回匹配结果。如果发现匹配,就返回一个数组,成员是匹配成功的子字符串,否则返回null。

    -------------------------------- exec方法的返回数组还包含以下两个属性:
    • input:整个原字符串。
    • index:整个模式匹配成功的开始位置(从0开始计数)。
        const one = /x(y+)z(c)/i;
        const result = one.exec('xyyzcccccc xyyyyyyyyyzc');
        console.log(one.source, 'source')
        console.log(result.input, '整个源字符串')
        console.log(result,'result')   
    
    说明:
    正则带括号,即组匹配时,exec()方法返回的数组,成员有多个,
    第一个成员是整个正则的匹配,
    第二个成员是第一个括号的匹配
    第三个成员是第二个括号的匹配
    ........
    exec()方法返回的数组中,还有两个属性
    input :整个原字符串
    index :整个模式匹配成功的开始位置
    
    结果:
    x(y+)z(c) source
    xyyzcccccc xyyyyyyyyyzc 整个源字符串
    ["xyyzc", "yy", "c", index: 0, input: "xyyzcccccc xyyyyyyyyyzc"] "result"
    
    
    
    -----------------------------------------------------------------------------------
    
    
    
    
        const one = /x(y+)z(c)/ig;      // 正则带有 g 修饰符
        one.lastIndex = 10;             // 指定开始搜索的位置,在带有 g 修饰符时
        const result = one.exec('xyyzcccccc xyyyyyyyyyzc');
        console.log(one.source, 'source')
        console.log(result.input, '整个源字符串')
        console.log(result,'result')
    
    说明:
    当正则带有 g 修饰符时,可以用 lastIndex 属性指定开始搜索的位置
    
    结果:
    x(y+)z(c) source
    xyyzcccccc xyyyyyyyyyzc 整个源字符串
    ["xyyyyyyyyyzc", "yyyyyyyyy", "c", index: 11, input: "xyyzcccccc xyyyyyyyyyzc"] "result"
    

    (3) 字符串的实例方法

    (1) String.prototype.match()

    匹配成功返回数组,匹配失败返回null

    • 当正则带有 g 修饰符时,match() 方法会一次性返回所有匹配成功的结果。
    • 设置正则表达式的lastIndex属性,对match方法无效
    var s = 'abba';
    var r = /a/g;
    
    s.match(r) // ["a", "a"]  
    r.exec(s) // ["a"]
    
    字符串的matc()方法   和   正则的exec() 方法的区别
    
    在有 g 修饰符时
    math()返回所有匹配成果的结果, exec() 只返回第一个匹配成功的子字符串
    

    (2) String.prototype.search() 返回匹配的位置

    (3) String.prototype.replace() 返回匹配的位置

    • 它接受两个参数,第一个是正则表达式,表示搜索模式,第二个是替换的内容。

    匹配规则

    (1) 字面量字符

    大部分字符在正则表达式中,就是字面的含义,比如/a/匹配a,/b/匹配b。如果在正则表达式之中,某个字符只表示它字面的含义(就像前面的a和b),那么它们就叫做“字面量字符”(literal characters)。

    • 只表示字面的含义的字符,是字面量字符。 ---- literal characters

    (2) 元字符

    除了字面量字符以外,还有一部分字符有特殊含义,不代表字面的意思。它们叫做“元字符”(metacharacters)

    • 特殊意义的字符,是元字符 ---- metacharacters

    点字符 ( . )

    • 点字符(.)匹配除回车(\r)、换行(\n) 、行分隔符(\u2028)和段分隔符(\u2029)以外的所有字符。
      . 点字符 匹配除了 ( 回车\r ),  ( 换行\n) ,  ( 行分隔符\u2028 ), ( 段分隔符\u2029 ) 以外的所有字符
    
      /r   是 return 的意思
      /n   是 new line 的意思
    

    位置字符( ^ $ )

    ^ 表示字符串的开始位置
    $ 表示字符串的结束位置
    
    

    选择符 ( | )

    多个选择符可以联合使用。

    选择符会包括它前后的多个字符,比如/ab|cd/指的是匹配ab或者cd,而不是指匹配b或者c。
    如果想修改这个行为,可以使用圆括号。

    竖线符号(|)在正则表达式中表示“或关系”(OR),即cat|dog表示匹配cat或dog。
    
    多个选择符可以联合使用。
    
    
    
    
    // 匹配fred、barney、betty之中的一个        ----- 匹配其中一个就行
    /fred|barney|betty/
    
    
    ----------------------------------------
    
    
    /a( |\t)b/.test('a\tb') // true
    a和b之间有一个空格或者一个制表符都能匹配成功。
    

    转义符 ( \ ) ---------- 需要转义的有12个字符

    正则表达式中那些有特殊含义的元字符,如果要匹配它们本身,就需要在它们前面要加上反斜杠。比如要匹配+,就要写成+

    • 正则表达式中,需要加反斜杠转移的字符,一共有 12 个 !!!!!!! ( 12个 )
    • 正则表达式中,需要反斜杠转义的,一共有12个字符:^.[$()|*+?{\\
    • 需要特别注意的是,如果使用RegExp方法生成正则对象,转义需要使用两个斜杠,因为字符串内部会先转义一次。
    需要转义的字符 12 个
    
    .                     ---- 点字符
    ^ $                   ---- 位置字符
    |                     ---- 选择符
    ?* +                 ---- 量词符
    [                     ---- 字符类符号, 左中括号
    {                     ---- 重复类符号, 左大括号
    ( )                   ---- 分组符
    \\                    ---- 双反斜杠, 转义 \ 反斜杠本身
    

    字符类

    字符类(class)表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内,比如[xyz] 表示x、y、z之中任选一个匹配。

    有两个字符在字符类中有特殊含义。

    (1) 脱字符(^)

    • 如果方括号内的第一个字符是[^],则表示除了字符类之中的字符,其他字符都可以匹

    • 如果方括号内没有其他字符,即只有[^],就表示匹配一切字符,其中包括换行符。相比之下,点号作为元字符(.)是不包括换行符的。

    • 注意,脱字符只有在字符类的第一个位置才有特殊含义,否则就是字面含义。(重要)

    [^xyz] 表示除了x、y、z之外都可以匹配。
    
    [^] 表示匹配一切字符,包括换行符
    
    
    
    . 点字符 : 匹配除了 /r /n /u2028 /u2029 字符外的所有字符
    
    
    var s = 'Please yes\nmake my day!';
    
    s.match(/yes.*day/) // null    
    s.match(/yes[^]*day/) // [ 'yes\nmake my day']
    
    

    (2) 连字符( - )

    某些情况下,对于连续序列的字符,连字符(-)用来提供简写形式,表示字符的连续范围。

    • 比如,[abc]可以写成[a-c],[0123456789]可以写成[0-9],同理[A-Z]表示26个大写字母。
    [1-31]
    
    [1-31],不代表1到31,只代表1到3。
    
    • 不要过分使用连字符,设定一个很大的范围,否则很可能选中意料之外的字符
      最典型的例子就是[A-z],表面上它是选中从大写的A到小写的z之间52个字母,但是由于在 ASCII 编码之中,大写字母与小写字母之间还有其他字符,结果就会出现意料之外的结果。
    /[A-z]/.test('\\') // true
    
    大写字母与小写字母之间还有其他字符
    

    预定义模式

    ( \b ) ---------------------- boundry 边界
    ( \s ) ---------------------- space 空格,空白,间隙的意思
    ( \d ) ---------------------- digit 数字

    \d 匹配0-9之间的任一数字,相当于[0-9]。
    \D 匹配所有0-9以外的字符,相当于[^0-9]。
    \w 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]。
    \W 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]。
    \s 匹配空格(包括换行符、制表符、空格符等),相等于[ \t\r\n\v\f]。
    \S 匹配非空格的字符,相当于[^ \t\r\n\v\f]。
    \b 匹配词的边界。
    \B 匹配非词边界,即在词的内部。
    

    注意:正则表达式遇到换行符(\n)就会停止匹配。

    var html = "<b>Hello</b>\n<i>world!</i>";
    /.*/.exec(html)[0]
    
    // "<b>Hello</b>"
    
    [\S\s]指代一切字符
    [\D\d]指代一切字符
    ...
    
    var html = "<b>Hello</b>\n<i>world!</i>";
    /[\S\s]*/.exec(html)[0]
    
    // "<b>Hello</b>\n<i>world!</i>"
    

    重复类

    模式的精确匹配次数,使用大括号({})表示。 ----------------------- 精确匹配次数

    • {n}表示恰好重复n次,
    • {n,}表示至少重复n次,
    • {n,m}表示重复不少于n次,不多于m次。

    量词符

    量词符用来设定某个模式出现的次数。

    ? 问号表示某个模式出现0次或1次,等同于{0, 1}。
    * 星号表示某个模式出现0次或多次,等同于{0,}。
    + 加号表示某个模式出现1次或多次,等同于{1,}。
    

    贪婪模式

    三个量词符,默认情况下都是最大可能匹配,即匹配直到下一个字符不满足匹配规则为止。这被称为贪婪模式。

    • 三个量词符? * +,默认是贪婪模式
    • 如果想将贪婪模式改为非贪婪模式,可以在量词符后面加一个问号。( 重要 )

    *?:表示某个模式出现0次或多次,匹配时采用非贪婪模式。
    +?:表示某个模式出现1次或多次,匹配时采用非贪婪模式。

    
    var s = 'aaa';
    
    s.match(/a+?/) // ["a"]
    
    

    修饰符

    修饰符(modifier)表示模式的附加规则,放在正则模式的最尾部。

    (1) g 修饰符
    默认情况下,第一次匹配成功后,正则对象就停止向下匹配了。g修饰符表示全局匹配(global),加上它以后,正则对象将匹配全部符合条件的结果,主要用于搜索和替换。

    var regex = /b/;
    var str = 'abba';
    
    regex.test(str); // true
    regex.test(str); // true
    regex.test(str); // true
    
    上面代码中,正则模式不含g修饰符,每次都是从字符串头部开始匹配。所以,连续做了三次匹配,都返回true。
    
    
    --------------------------------
    
    var regex = /b/g;
    var str = 'abba';
    
    regex.test(str); // true
    regex.test(str); // true
    regex.test(str); // false
    
    上面代码中,正则模式含有g修饰符,每次都是从上一次匹配成功处,开始向后匹配。
    因为字符串abba只有两个b,所以前两次匹配结果为true,第三次匹配结果为false。
    
    

    (2) i 修饰符
    默认情况下,正则对象区分字母的大小写,加上i修饰符以后表示忽略大小写(ignorecase)。

    (3) m 修饰符 ---- 多行匹配,可以在位置符前后位置匹配 \n 换行符
    m修饰符表示多行模式(multiline),会修改^$的行为。默认情况下(即不加m修饰符时),^$匹配字符串的开始处和结尾处,加上m修饰符以后,^$还会匹配行首和行尾,即^和$会识别换行符(\n)。

    /world$/.test('hello world\n') // false  
    
    /world$/m.test('hello world\n') // true    
    
    -----------------------------------------/m可以匹配换行符 
    
    
    
    
    var s = 'ab\n';
    var r = /ab$/m;
    console.log( r.test(s) );     //true
    
    
    
    
    /^b/m.test('a\nb') // true
    上面代码要求匹配行首的b,如果不加m修饰符,就相当于b只能处在字符串的开始处。
    加上b修饰符以后,换行符\n也会被认为是一行的开始。
    

    组匹配

    正则表达式的括号表示分组匹配,括号中的模式可以用来匹配分组的内容。

    • 注意,使用组匹配时,不宜同时使用g修饰符,否则match方法不会捕获分组的内容。
    var m = 'abcabc'.match(/(.)b(.)/);
    m
    // ['abc', 'a', 'c']
    
    
    说明:
    match正则内有括号时,返回的数组,第一个成员是全部的正则匹配,第二个成员是第一个括号的匹配,以此类推...
    
    • 注意,使用组匹配时,不宜同时使用g修饰符,否则match方法不会捕获分组的内容。
    var m = 'abcabc'.match(/(.)b(.)/g);
    m // ['abc', 'abc']
    
    
    上面代码使用带g修饰符的正则表达式,结果match方法只捕获了匹配整个表达式的部分。
    
    这时必须使用正则表达式的exec方法,配合循环,才能读到每一轮匹配的组捕获。
    

    相关文章

      网友评论

        本文标题:normalizr

        本文链接:https://www.haomeiwen.com/subject/ycxneftx.html