Last active
June 12, 2016 01:25
-
-
Save evturn/be1d9b43fea2ad64021a603377a0131d to your computer and use it in GitHub Desktop.
Create Collections of Immutable Maps
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class RecordMap { | |
set(map, record) { | |
if (map && !record) { | |
record = map | |
map = Immutable.Map() | |
} | |
return map.set(record.id, new Record(record)) | |
} | |
setGroup(map, data) { | |
if (map && !data) { | |
data = map | |
map = Immutable.Map() | |
} | |
data.map(x => map = this.set(map, x)) | |
return map | |
} | |
update(map, record, updater) { | |
return map.update(record.id, updater) | |
} | |
merge(maps) { | |
return maps.reduce((acc, x, i) => { | |
acc = acc.merge(x) | |
return acc | |
}, Immutable.Map()) | |
} | |
delete(map, record) { | |
return map.delete(record.id, record) | |
} | |
clear(map) { | |
return map.clear() | |
} | |
} | |
class Record { | |
constructor(props) { | |
this.id = props.id | |
this.title = props.title | |
this.more = props.more | |
this.parentID = props.parentID | |
} | |
} | |
const data = [{ | |
id: 1, | |
title: 'Call the cops', | |
more: 'Because someone is currently breaking into my apartment', | |
parentID: false | |
},{ | |
id: 2, | |
title: 'Towels', | |
more: 'Get better towels.', | |
parentID: 8 | |
},{ | |
id: 3, | |
title: 'Drink cake', | |
more: 'Make sure to save some for Craig.', | |
parentID: 11 | |
},{ | |
id: 4, | |
title: 'Paint kitchen', | |
more: 'Go to a store and buy supplies', | |
parentID: 8 | |
},{ | |
id: 5, | |
title: 'Burgers', | |
more: 'Try that new place by Craig and do not invite Craig.', | |
parentID: 11 | |
},{ | |
id: 6, | |
title: 'Flight to Montréal', | |
more: 'Check your ticket.', | |
parentID: false | |
},{ | |
id: 7, | |
title: 'Cables', | |
more: 'Surge protector.', | |
parentID: 8 | |
},{ | |
id: 8, | |
title: 'Household items', | |
more: 'Kitchen, bathroom, etc', | |
parentID: false | |
},{ | |
id: 9, | |
title: 'New display', | |
more: '20:9 aspect ratio with rocket launchers on each side', | |
parentID: 8 | |
},{ | |
id: 10, | |
title: 'Salt as an entreé', | |
more: 'This could be good for Thanksgiving.', | |
parentID: 11 | |
},{ | |
id: 11, | |
title: 'Eating', | |
more: 'Places, even just food in general.', | |
parentID: false | |
}] | |
const data2 = [{ | |
id: 12, | |
title: 'Call the cops', | |
more: 'Because someone is currently breaking into my apartment', | |
parentID: false | |
},{ | |
id: 22, | |
title: 'Towels', | |
more: 'Get better towels.', | |
parentID: 8 | |
},{ | |
id: 32, | |
title: 'Drink cake', | |
more: 'Make sure to save some for Craig.', | |
parentID: 11 | |
},{ | |
id: 42, | |
title: 'Paint kitchen', | |
more: 'Go to a store and buy supplies', | |
parentID: 8 | |
},{ | |
id: 52, | |
title: 'Burgers', | |
more: 'Try that new place by Craig and do not invite Craig.', | |
parentID: 11 | |
},{ | |
id: 62, | |
title: 'Flight to Montréal', | |
more: 'Check your ticket.', | |
parentID: false | |
},{ | |
id: 72, | |
title: 'Cables', | |
more: 'Surge protector.', | |
parentID: 8 | |
},{ | |
id: 82, | |
title: 'Household items', | |
more: 'Kitchen, bathroom, etc', | |
parentID: false | |
},{ | |
id: 92, | |
title: 'New display', | |
more: '20:9 aspect ratio with rocket launchers on each side', | |
parentID: 8 | |
},{ | |
id: 102, | |
title: 'Salt as an entreé', | |
more: 'This could be good for Thanksgiving.', | |
parentID: 11 | |
},{ | |
id: 112, | |
title: 'Eating', | |
more: 'Places, even just food in general.', | |
parentID: false | |
}] | |
const map = new RecordMap(); | |
const map1 = map.setGroup(data) | |
const map2 = map.setGroup(data2) | |
const map3 = map.set({ | |
id: 201, | |
title: 'Chicken nuggets', | |
more: 'With bbq sauce' | |
}) | |
console.log(map3.get(201)) | |
/* | |
* [object Object] { | |
* id: 201, | |
* more: "With bbq sauce", | |
* parentID: undefined, | |
* title: "Chicken nuggets" | |
* } | |
*/ | |
const map4 = map1.merge(map2) | |
const map5 = map.set({ | |
id: 201, | |
title: 'Turkey nuggets', | |
more: 'Maybe no.' | |
}) | |
console.log(map5.get(201)) | |
/* | |
* [object Object] { | |
* id: 201, | |
* more: "Maybe no.", | |
* parentID: undefined, | |
* title: "Turkey nuggets" | |
* } | |
*/ | |
map.update(map5, map5.get(201), x => { | |
x.title = 'Hi I completely changed your title' | |
return x | |
}) | |
console.log(map5.get(201)) | |
/* | |
* [object Object] { | |
* id: 201, | |
* more: "Maybe no.", | |
* parentID: undefined, | |
* title: "Hi I completely changed your title" | |
* } | |
*/ | |
map.update(map3, map3.get(201), x => { | |
x.title = map5.get(201).title | |
return x | |
}) | |
console.log(map3.get(201)) | |
/* | |
* [object Object] { | |
* id: 201, | |
* more: "With bbq sauce", | |
* parentID: undefined, | |
* title: "Hi I completely changed your title" | |
* } | |
*/ | |
const map6 = map.merge([map1, map2, map5]) | |
const map7 = map.merge([map1, map2, map3, map5]) | |
const map8 = map.set(map7, { | |
id: 300, | |
title: 'Cool stuff', | |
more: 'To be determined' | |
}) | |
console.log(map7.get(300)) | |
// undefined | |
console.log(map8.get(300)) | |
/* | |
* [object Object] { | |
* id: 300, | |
* more: "To be determined", | |
* parentID: undefined, | |
* title: "Cool stuff" | |
* } | |
*/ | |
console.log(map1.size) | |
// 11 | |
console.log(map2.size) | |
// 11 | |
console.log(map3.size) | |
// 1 | |
console.log(map4.size) | |
// 22 | |
console.log(map5.size) | |
// 1 | |
console.log(map6.size) | |
// 23 | |
console.log(map7.size) | |
// 23 | |
console.log(map8.size) | |
// 24 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { OrderedMap } = Immutable | |
const initialState = __INITIAL_STATE__ | |
function createMap(data) { | |
return data | |
.filter(hasNoParents) | |
.map(x => ({ ...x, kids: data.filter(filterKids(x))})) | |
.map(x => ({ ...x, kids: setKids(x) })) | |
.reduce(reduceToMap, OrderedMap()) | |
} | |
const hasNoParents = x => !x.parentID | |
const reduceToMap = (acc, x) => ( | |
acc = acc.set(x.id, x) | |
) | |
const filterKids = x => ( | |
x2 => x2.parentID == x.id | |
) | |
const setKids = ({ kids }) => ( | |
kids.length ? kids.reduce(reduceToMap, OrderedMap()) : false | |
) | |
const map = createMap(initialState) | |
console.log(initialState.length) | |
// 11 | |
console.log(map.size) | |
// 4 | |
console.log(map.get(8).kids.size) | |
// 4 | |
console.log(map.get(11).kids.size) | |
// 3 | |
console.log(map.toJS()) | |
/* | |
* [object Object] { | |
* 1: [object Object] { | |
* id: 1, | |
* kids: false, | |
* more: "Because someone is currently breaking into my apartment", | |
* parentID: false, | |
* title: "Call the cops" | |
* }, | |
* 11: [object Object] { | |
* id: 11, | |
* kids: [object Object] { ... }, | |
* more: "Places, even just food in general.", | |
* parentID: false, | |
* title: "Eating" | |
* }, | |
* 6: [object Object] { | |
* id: 6, | |
* kids: false, | |
* more: "Check your ticket.", | |
* parentID: false, | |
* title: "Flight to Montréal" | |
* }, | |
* 8: [object Object] { | |
* id: 8, | |
* kids: [object Object] { ... }, | |
* more: "Kitchen, bathroom, etc", | |
* parentID: false, | |
* title: "Household items" | |
* } | |
* } | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment