今天写代码遇到一个问题就是关于二维数组去重的解决方案。
比如[[1,2,3], [2, 3, 4], [1, 2, 3]]如何删除这个
当初打算用reduce或者map的Array原型链上的方法做的,但是效率实在是太慢了,而且代码巨丑
一下是相对来说比较优雅的方法
var arr = [["aa","bb","cc"],["aa","bb","cc"],["b","b","v"]];
var hash = {};
var result = [];
for(var i = 0, len = arr.length; i < len; i++){
if(!hash[arr[i]]){
result.push(arr[i]);
hash[arr[i]] = true;
}
}
使用hash这个概念,这样hash所指向的方向就不是一个了
xiaowzx
@xiaowzx
xiaowzx 发布的帖子
-
奇技淫巧二维数组去重
-
Redux浅析
redux介绍
可以理解为一种web的状态管理机制,其大致哲学就是要求数据->component之间的关系,常常和redux一起常常出现共同使用,但是其实也可以单独使用,用的技术比较原生所以还ok。首先react中使用redux的主要原因是因为react的组建之间通信代码的整洁性,比如子父组件的通信:
ParentChild
如果在一个复杂的项目tree中可能有兄弟组件的通信等等问题,那么redux可以用来起简化操作的作用,毕竟是reduce是减少的意思嘛,redux大概就是减少操作流程的意思了。
根据Redux Flow的原理,其实很清晰,大概就是普通的flux设计模式,即只需要是把dispatch改变store,每一个同步事件+异步事件结束之后把其同步到state中,就把关于数据的控制权交给了React了。
代码就可以写成这样了
import React, { Component } from 'react'; import './App.css'; import Test from "./Test"; import { connect } from "react-redux"; import {change} from "./action.js" //把state里面的值注入到connect中 // const mapStateToProps = state => ({ // a: state.rootReducer // }); const mapStateToProps = state => { return { a: state.changeStore } } //把action注入到props中 const mapDispatchToProps = dispatch => ({ change: num => dispatch(change(num)) }) //Parent class App extends Component { constructor(props) { super(props); } render() { return ( <div className="App"> {this.props.a} <Test/> <button onClick={()=>{ console.log(1); this.props.change(12); }}>test </button> </div> ); } } export default connect( mapStateToProps, mapDispatchToProps )(App)
其实相当于一个装饰器的设计模式,可以用ES7的设计模式,但是懒得装babel插件~用装饰器模式代码会简洁不少。
源码
可以看看redux的源文件可以说是代码各个文件都相当的简洁了,其中index.js就是一个export各个接口的闭包过程
Compose.js
其中compose.js主要是一个工具代码,会在之后的逻辑文件中调用,起大致作用就是代码组合的作用,比如把函数f(), g(), 和 h() 组合起来可以得到复合函数 f(g(h()))的作用,一个简单的测试程序
可以看出该函数是先执行test2再执行test1,是一种很常见的函数式编程的思想,在Redux中主要是用来做中间件的作用,中间件其实可以用多种方法实现(也有递归等方法,比如koa2的实现方法)
createStrore.js
这个是创建store的关键Function,可以先focus这个函数的返回值
其实我们主要用到的是前3个方法,所以主要关注这个就好了
dispatch
工作是连接action到reducer,其本质就是提供唯一一个可以修改store内的数据的方法,这一点符合React的设计模式(不可以直接修改state中的值)
其实dispatch的参数只有一个action的Object,前面的代码都是进行异常处理的,所以写代码也应该把对于参数的处理放在函数的前面,可以看出逻辑代码也很简单的,首先注明开始dispatch的状态,然后让action和当前的currentState中放到reducer中进行merge,最后修改currentState的状态;之后把每一个订阅者(listener)都唤醒一遍,最后返回这个action的值getState
其实这个方法起了两个作用,第一个是保证了store的属性只可读性,第二个就是如果不允许在执行dispatch的时候读取store属性,虽然按照道理来说dispatch这个过程应该是一个阻塞的过程,所以这个场景我暂时没有想到
subscribe
这个作用是订阅数据在dispatch的过程之后,产生listener的作用,应该在react-redux这个库中是很常见的功能,就是一个简单的观察者模式(设计模式中)
applyMiddleware.js
这个功能就是为Redux的开发过程增加中间件这个属性,其实他的原理就是修改了dispatch这个函数的功能,从而可以达到原生,dispatch并不可以达到的功能。
首先复习一下applyMiddleware这个玩意怎么写
这里就必须回到createStore.js这个处理中了
把它翻译成中文就是:
如果createStore有enhancer这个参数,并且enhancer的类型是一个function,那么就不会返回虾米拿到闭包,而是调用这个enhancer这个方法了。所以这就是applyMiddleware中可以拿到createStore以及调用createStore这个函数的参数了(reducer, preloadedState),接下来的操作就很简单了,东西都拿到了链式调用就可以了
当然了也有些trick就是把dispatch和getState这两个api打包给了中间件
最后就是一个小的中间件DEMO啰,可以看出了虽然dispatch这个东西好用,但是只是一个同步的操作,设想一下如果我写的action中的这个数据是一个异步才可以拿到的数据,但是dispatch是一个同步的事件,那么去执行的时候,肯定会和预期有差别,那么一个facebook的大佬写了下面的中间的代码~
10000个赞了23333
其实代码很简单只有几行,可以看出来这里面就有我们的dispatch啊,getState,next就是要传递的修改厚度disptach方法啰,这样action所返回的值就可以不仅仅只有是object了还可以返回一个Fun。tion了,异步问题也就解决了~