JavaScript:中味をあんまり気にしないでディープコピーできる関数
JavaScript:中味をあんまり気にしないでディープコピーできる関数:
前記事の続きです。
引数の中味をあんまり気にしないでディープコピーできる関数cloneです。
前記事ではこう書きました。
基本的にはこれで動くのですが、込み入ったオブジェクトに使うと動作が鈍いときがあります。
mapForMap,mapForSetで新しい配列を作っては捨てているところがあるので、そこをちょっと節約してみました。
だいぶ動作が速くなった感があります。
さらにforEachで新たに配列を作らない方法にしてみました。
mapForObjでは直接forEachできませんが、なるべく小さい(entries()でなくkeys())配列を作って回すようにしてみました。
実用上はこれで十分かな。
前記事の続きです。
引数の中味をあんまり気にしないでディープコピーできる関数cloneです。
前記事ではこう書きました。
const mapForMap = f => a => new Map( [...a].map( ([key, value]) =>[key, f(value)] ) ); const mapForSet = f => a => new Set( [...a].map( f ) ); const entriesMapIntoObj = f => xs => xs.reduce( (acc, [key, value]) => ({ ...acc, [key]:f(value) }) , {} ); const mapForObj = f => a => entriesMapIntoObj( f )( Object.entries( a ) ); const getType = a => Object.prototype.toString.call(a); const clone = a => { const type = getType( a ); return (type === "[object Array]")? a.map( clone ) :(type === "[object Map]")? mapForMap( clone )( a ) :(type === "[object Set]")? mapForSet( clone )( a ) :(type === "[object Object]")? mapForObj( clone )( a ) :(type === "[object Date]")? new Date( a ) : a; }
mapForMap,mapForSetで新しい配列を作っては捨てているところがあるので、そこをちょっと節約してみました。
const mapForMap = f => a => [...a].reduce( (acc,[key, value])=>acc.set(key, f(value)), new Map()); const mapForSet = f => a => [...a].reduce((acc, e)=>acc.add(f(e)), new Set());
さらにforEachで新たに配列を作らない方法にしてみました。
mapForObjでは直接forEachできませんが、なるべく小さい(entries()でなくkeys())配列を作って回すようにしてみました。
const mapForMap = f => a => { const b = new Map(); a.forEach((key, value)=>b.set(key,f(value))); return b; } const mapForSet = f => a =>{ const b = new Set(); a.forEach(e=>b.add(f(e))); return b; } const mapForObj = f => a =>{ const b = {}; Object.keys(a).forEach( e => b[e] = f(a[e]) ); return b; } const getType = a => Object.prototype.toString.call(a); const clone = a => { const type = getType( a ); return (type === "[object Array]")? a.map( clone ) :(type === "[object Map]")? mapForMap( clone )( a ) :(type === "[object Set]")? mapForSet( clone )( a ) :(type === "[object Object]")? mapForObj( clone )( a ) :(type === "[object Date]")? new Date( a ) : a; }
コメント
コメントを投稿