Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save a-bronx/832b837aee7db2b1baf4ee612fb4a3f8 to your computer and use it in GitHub Desktop.
Save a-bronx/832b837aee7db2b1baf4ee612fb4a3f8 to your computer and use it in GitHub Desktop.

Revisions

  1. Elliot Larson revised this gist Jun 21, 2018. 2 changed files with 7 additions and 14 deletions.
    9 changes: 3 additions & 6 deletions immutable-operations.spec.js
    Original file line number Diff line number Diff line change
    @@ -6,14 +6,13 @@
    // * Immutable.js
    // * Lodash
    // * Rambda
    // * Imu (file below)
    //
    // The motivation for this is largely to work with a Redux store.

    import R from "rambda";
    import _ from "lodash";
    import { Map, List } from "immutable";
    import * as I from "./imu";
    import * as I from "../helpers/imu";

    describe("immutable Array operations", () => {
    let characters;
    @@ -152,8 +151,7 @@ describe("immutable Array operations", () => {

    describe("with imu set", () => {
    it("returns the expected result", () => {
    const updateIndex = characters.findIndex(c => c === characterToUpdate);
    const result = I.set(characters, updateIndex, updatedName);
    const result = I.set(characters, characterToUpdate, updatedName);
    expect(result).toEqual(expectedResult);
    });
    });
    @@ -205,8 +203,7 @@ describe("immutable Array operations", () => {

    describe("with imu del", () => {
    it("returns the expected result", () => {
    const removeIndex = characters.findIndex(c => c === characterToRemove);
    const result = I.del(characters, removeIndex);
    const result = I.del(characters, characterToRemove);
    expect(result).toEqual(expectedResult);
    });
    });
    12 changes: 4 additions & 8 deletions imu.js
    Original file line number Diff line number Diff line change
    @@ -24,12 +24,8 @@ export const set = (target, ...args) => {
    }
    };

    const aSet = (array, updateIndex, updateValue) => {
    return [
    ...array.slice(0, updateIndex),
    updateValue,
    ...array.slice(updateIndex + 1),
    ];
    const aSet = (array, oldValue, newValue) => {
    return array.map(ai => (ai === oldValue ? newValue : ai));
    };

    const oSet = (object, updateKey, updateValue) => {
    @@ -47,8 +43,8 @@ export const del = (target, ...args) => {
    }
    };

    const aDel = (array, deleteIndex) => {
    return [...array.slice(0, deleteIndex), ...array.slice(deleteIndex + 1)];
    const aDel = (array, deleteValue) => {
    return array.filter(ai => ai !== deleteValue);
    };

    const oDel = (obj, deleteKey) => {
  2. Elliot Larson revised this gist Jun 21, 2018. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions immutable-operations.spec.js
    Original file line number Diff line number Diff line change
    @@ -6,6 +6,7 @@
    // * Immutable.js
    // * Lodash
    // * Rambda
    // * Imu (file below)
    //
    // The motivation for this is largely to work with a Redux store.

  3. Elliot Larson revised this gist Jun 21, 2018. 1 changed file with 0 additions and 57 deletions.
    57 changes: 0 additions & 57 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -1,57 +0,0 @@
    // A tiny libary for making immutable changes to arrays and objects

    export const add = (target, ...args) => {
    if (Array.isArray(target)) {
    return aAdd(target, ...args);
    } else {
    return oAdd(target, ...args);
    }
    };

    const aAdd = (array, newValue) => {
    return [...array, newValue];
    };

    const oAdd = (obj, newKey, newValue) => {
    return { ...obj, [newKey]: newValue };
    };

    export const set = (target, ...args) => {
    if (Array.isArray(target)) {
    return aSet(target, ...args);
    } else {
    return oSet(target, ...args);
    }
    };

    const aSet = (array, updateIndex, updateValue) => {
    return [
    ...array.slice(0, updateIndex),
    updateValue,
    ...array.slice(updateIndex + 1),
    ];
    };

    const oSet = (object, updateKey, updateValue) => {
    return {
    ...object,
    [`${updateKey}`]: updateValue,
    };
    };

    export const del = (target, ...args) => {
    if (Array.isArray(target)) {
    return aDel(target, ...args);
    } else {
    return oDel(target, ...args);
    }
    };

    const aDel = (array, deleteIndex) => {
    return [...array.slice(0, deleteIndex), ...array.slice(deleteIndex + 1)];
    };

    const oDel = (obj, deleteKey) => {
    const { [`${deleteKey}`]: deleted, ...result } = obj;
    return result;
    };
  4. Elliot Larson revised this gist Jun 21, 2018. 1 changed file with 57 additions and 0 deletions.
    57 changes: 57 additions & 0 deletions imu.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,57 @@
    // A tiny libary for making immutable changes to arrays and objects

    export const add = (target, ...args) => {
    if (Array.isArray(target)) {
    return aAdd(target, ...args);
    } else {
    return oAdd(target, ...args);
    }
    };

    const aAdd = (array, newValue) => {
    return [...array, newValue];
    };

    const oAdd = (obj, newKey, newValue) => {
    return { ...obj, [newKey]: newValue };
    };

    export const set = (target, ...args) => {
    if (Array.isArray(target)) {
    return aSet(target, ...args);
    } else {
    return oSet(target, ...args);
    }
    };

    const aSet = (array, updateIndex, updateValue) => {
    return [
    ...array.slice(0, updateIndex),
    updateValue,
    ...array.slice(updateIndex + 1),
    ];
    };

    const oSet = (object, updateKey, updateValue) => {
    return {
    ...object,
    [`${updateKey}`]: updateValue,
    };
    };

    export const del = (target, ...args) => {
    if (Array.isArray(target)) {
    return aDel(target, ...args);
    } else {
    return oDel(target, ...args);
    }
    };

    const aDel = (array, deleteIndex) => {
    return [...array.slice(0, deleteIndex), ...array.slice(deleteIndex + 1)];
    };

    const oDel = (obj, deleteKey) => {
    const { [`${deleteKey}`]: deleted, ...result } = obj;
    return result;
    };
  5. Elliot Larson revised this gist Jun 21, 2018. 2 changed files with 114 additions and 5 deletions.
    57 changes: 57 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,57 @@
    // A tiny libary for making immutable changes to arrays and objects

    export const add = (target, ...args) => {
    if (Array.isArray(target)) {
    return aAdd(target, ...args);
    } else {
    return oAdd(target, ...args);
    }
    };

    const aAdd = (array, newValue) => {
    return [...array, newValue];
    };

    const oAdd = (obj, newKey, newValue) => {
    return { ...obj, [newKey]: newValue };
    };

    export const set = (target, ...args) => {
    if (Array.isArray(target)) {
    return aSet(target, ...args);
    } else {
    return oSet(target, ...args);
    }
    };

    const aSet = (array, updateIndex, updateValue) => {
    return [
    ...array.slice(0, updateIndex),
    updateValue,
    ...array.slice(updateIndex + 1),
    ];
    };

    const oSet = (object, updateKey, updateValue) => {
    return {
    ...object,
    [`${updateKey}`]: updateValue,
    };
    };

    export const del = (target, ...args) => {
    if (Array.isArray(target)) {
    return aDel(target, ...args);
    } else {
    return oDel(target, ...args);
    }
    };

    const aDel = (array, deleteIndex) => {
    return [...array.slice(0, deleteIndex), ...array.slice(deleteIndex + 1)];
    };

    const oDel = (obj, deleteKey) => {
    const { [`${deleteKey}`]: deleted, ...result } = obj;
    return result;
    };
    62 changes: 57 additions & 5 deletions immutable-operations.spec.js
    Original file line number Diff line number Diff line change
    @@ -1,19 +1,20 @@
    // This is a Jest spec that explores some of the different ways to alter
    // This is a Jest spec that explores some of the different ways to alter
    // arrays and objects without mutating state. I'm trying different approaches
    // available using:
    //
    //
    // * Vanilla JS
    // * Immutable.js
    // * Lodash
    // * Rambda
    //
    //
    // The motivation for this is largely to work with a Redux store.

    import R from "rambda";
    import _ from "lodash";
    import { Map, List } from "immutable";
    import * as I from "./imu";

    describe("immutable Array modifications", () => {
    describe("immutable Array operations", () => {
    let characters;

    beforeEach(() => {
    @@ -74,6 +75,13 @@ describe("immutable Array modifications", () => {
    expect(result.toArray()).toEqual(expectedResult);
    });
    });

    describe("with imu add", () => {
    it("returns the expected result", () => {
    const result = I.add(characters, newCharacter);
    expect(result).toEqual(expectedResult);
    });
    });
    });

    describe("update an item in an array", () => {
    @@ -140,6 +148,14 @@ describe("immutable Array modifications", () => {
    expect(result.toArray()).toEqual(expectedResult);
    });
    });

    describe("with imu set", () => {
    it("returns the expected result", () => {
    const updateIndex = characters.findIndex(c => c === characterToUpdate);
    const result = I.set(characters, updateIndex, updatedName);
    expect(result).toEqual(expectedResult);
    });
    });
    });

    describe("remove an item from an array", () => {
    @@ -185,10 +201,18 @@ describe("immutable Array modifications", () => {
    expect(result.toArray()).toEqual(expectedResult);
    });
    });

    describe("with imu del", () => {
    it("returns the expected result", () => {
    const removeIndex = characters.findIndex(c => c === characterToRemove);
    const result = I.del(characters, removeIndex);
    expect(result).toEqual(expectedResult);
    });
    });
    });
    });

    describe("immutable Object modifications", () => {
    describe("immutable Object operations", () => {
    let characters;

    beforeEach(() => {
    @@ -229,6 +253,15 @@ describe("immutable Object modifications", () => {
    expect(result.toObject()).toEqual(expectedResult);
    });
    });

    describe("with imu add", () => {
    it("returns the expected results", () => {
    const newId = 4;
    const newCharacter = { firstName: "Maude", lastName: "Lebowski" };
    const result = I.add(characters, newId, newCharacter);
    expect(result).toEqual(expectedResult);
    });
    });
    });

    describe("update an object key's value", () => {
    @@ -266,6 +299,18 @@ describe("immutable Object modifications", () => {
    expect(result.toObject()).toEqual(expectedResult);
    });
    });

    describe("with imu set", () => {
    it("returns the expected results", () => {
    const updateId = 1;
    const updatedCharacter = {
    firstName: "The Dude",
    lastName: "Lebowski",
    };
    const result = I.set(characters, updateId, updatedCharacter);
    expect(result).toEqual(expectedResult);
    });
    });
    });

    describe("delete an object's key", () => {
    @@ -324,5 +369,12 @@ describe("immutable Object modifications", () => {
    expect(result.toObject()).toEqual(expectedResult);
    });
    });

    describe("with imu del", () => {
    it("returns the expected results", () => {
    const result = I.del(characters, deleteId);
    expect(result).toEqual(expectedResult);
    });
    });
    });
    });
  6. Elliot Larson revised this gist Jun 20, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion immutable-operations.spec.js
    Original file line number Diff line number Diff line change
    @@ -300,7 +300,7 @@ describe("immutable Object modifications", () => {
    });
    });

    describe("with lodhash omit", () => {
    describe("with lodash omit", () => {
    it("returns the expected results", () => {
    // note that we can pass in an integer key here and it handles it without needing to type cast
    const result = _.omit(characters, deleteId);
  7. Elliot Larson renamed this gist Jun 20, 2018. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  8. Elliot Larson created this gist Jun 20, 2018.
    328 changes: 328 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,328 @@
    // This is a Jest spec that explores some of the different ways to alter
    // arrays and objects without mutating state. I'm trying different approaches
    // available using:
    //
    // * Vanilla JS
    // * Immutable.js
    // * Lodash
    // * Rambda
    //
    // The motivation for this is largely to work with a Redux store.

    import R from "rambda";
    import _ from "lodash";
    import { Map, List } from "immutable";

    describe("immutable Array modifications", () => {
    let characters;

    beforeEach(() => {
    characters = ["Walter", "Jeffrey", "Donald"];
    });

    describe("add item to an array", () => {
    let expectedResult, newCharacter;

    beforeEach(() => {
    newCharacter = "Maude";
    expectedResult = ["Walter", "Jeffrey", "Donald", "Maude"];
    });

    describe("with vanilla JS spread operator", () => {
    it("returns the expected result", () => {
    const result = [...characters, newCharacter];
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with vanilla JS concat", () => {
    it("returns the expected result", () => {
    const result = characters.concat(newCharacter);
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with lodash concat", () => {
    it("returns the expected result", () => {
    const result = _.concat(characters, newCharacter);
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with Ramda append", () => {
    it("returns the expected result", () => {
    const result = R.append(newCharacter, characters);
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with Immutable.js push", () => {
    it("returns the expected result", () => {
    const immutableCharacters = List(characters);
    const result = immutableCharacters.push(newCharacter);
    expect(result.toArray()).toEqual(expectedResult);
    });
    });

    describe("with Immutable.js set", () => {
    it("returns the expected result", () => {
    const immutableCharacters = List(characters);
    const result = immutableCharacters.set(
    immutableCharacters.size,
    newCharacter,
    );
    expect(result.toArray()).toEqual(expectedResult);
    });
    });
    });

    describe("update an item in an array", () => {
    let expectedResult, characterToUpdate, updatedName;

    beforeEach(() => {
    characterToUpdate = "Jeffrey";
    updatedName = "The Dude";
    expectedResult = ["Walter", "The Dude", "Donald"];
    });

    describe("with vanilla JS map", () => {
    it("returns the expected result", () => {
    const result = characters.map(c => {
    if (c === characterToUpdate) {
    return updatedName;
    }
    return c;
    });
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with vanilla JS findIndex, spread operator, and slice", () => {
    it("returns the expected result", () => {
    const updateIndex = characters.findIndex(c => c === characterToUpdate);
    const result = [
    ...characters.slice(0, updateIndex),
    updatedName,
    ...characters.slice(updateIndex + 1),
    ];
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with Ramda findIndex and update", () => {
    it("returns the expected result", () => {
    const updateIndex = R.findIndex(R.equals(characterToUpdate))(
    characters,
    );
    const result = R.update(updateIndex, updatedName, characters);
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with Immutable.js findIndex and splice", () => {
    it("returns the expected result", () => {
    const immutableCharacters = List(characters);
    const updateIndex = immutableCharacters.findIndex(
    c => c === characterToUpdate,
    );
    const result = immutableCharacters.splice(updateIndex, 1, updatedName);
    expect(result.toArray()).toEqual(expectedResult);
    });
    });

    describe("with Immutable.js findIndex and set", () => {
    it("returns the expected result", () => {
    const immutableCharacters = List(characters);
    const updateIndex = immutableCharacters.findIndex(
    c => c === characterToUpdate,
    );
    const result = immutableCharacters.set(updateIndex, updatedName);
    expect(result.toArray()).toEqual(expectedResult);
    });
    });
    });

    describe("remove an item from an array", () => {
    let expectedResult, characterToRemove;

    beforeEach(() => {
    characterToRemove = "Donald";
    expectedResult = ["Walter", "Jeffrey"];
    });

    describe("with vanillla JS filter", () => {
    it("returns the expected result", () => {
    const result = characters.filter(c => c !== characterToRemove);
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with vanillla JS findIndex and slice", () => {
    it("returns the expected result", () => {
    const removeIndex = characters.findIndex(c => c === characterToRemove);
    const result = [
    ...characters.slice(0, removeIndex),
    ...characters.slice(removeIndex + 1),
    ];
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with Rambda reject", () => {
    it("returns the expected result", () => {
    const result = R.reject(R.equals(characterToRemove), characters);
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with Immutable.js remove", () => {
    it("returns the expected result", () => {
    const immutableCharacters = List(characters);
    const removeIndex = immutableCharacters.findIndex(
    c => c === characterToRemove,
    );
    const result = immutableCharacters.remove(removeIndex);
    expect(result.toArray()).toEqual(expectedResult);
    });
    });
    });
    });

    describe("immutable Object modifications", () => {
    let characters;

    beforeEach(() => {
    characters = {
    1: { firstName: "Jeffrey", lastName: "Lebowski" },
    2: { firstName: "Walter", lastName: "Sobchak" },
    3: { firstName: "Donald", lastName: "Kerabatsos" },
    };
    });

    describe("add a key to an object", () => {
    let expectedResult;

    beforeEach(() => {
    expectedResult = {
    1: { firstName: "Jeffrey", lastName: "Lebowski" },
    2: { firstName: "Walter", lastName: "Sobchak" },
    3: { firstName: "Donald", lastName: "Kerabatsos" },
    4: { firstName: "Maude", lastName: "Lebowski" },
    };
    });

    describe("with vanilla JS spread operator", () => {
    it("returns the expected results", () => {
    const newId = 4;
    const newCharacter = { firstName: "Maude", lastName: "Lebowski" };
    const result = { ...characters, [newId]: newCharacter };
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with Immutable.js set", () => {
    it("returns the expected results", () => {
    const newId = 4;
    const newCharacter = { firstName: "Maude", lastName: "Lebowski" };
    const immutableCharacters = Map(characters);
    const result = immutableCharacters.set(newId, newCharacter);
    expect(result.toObject()).toEqual(expectedResult);
    });
    });
    });

    describe("update an object key's value", () => {
    let expectedResult;

    beforeEach(() => {
    expectedResult = {
    1: { firstName: "The Dude", lastName: "Lebowski" },
    2: { firstName: "Walter", lastName: "Sobchak" },
    3: { firstName: "Donald", lastName: "Kerabatsos" },
    };
    });

    describe("with vanilla JS spread operator", () => {
    it("returns the expected results", () => {
    const updateId = 1;
    const updatedcharacter = {
    firstName: "The Dude",
    lastName: "Lebowski",
    };
    const result = { ...characters, [updateId]: updatedcharacter };
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with Immutable.js set", () => {
    it("returns the expected results", () => {
    const immutableCharacters = Map(characters);
    const updateId = 1;
    const updatedcharacter = {
    firstName: "The Dude",
    lastName: "Lebowski",
    };
    const result = immutableCharacters.set(`${updateId}`, updatedcharacter);
    expect(result.toObject()).toEqual(expectedResult);
    });
    });
    });

    describe("delete an object's key", () => {
    let expectedResult, deleteId;

    beforeEach(() => {
    deleteId = 3;
    expectedResult = {
    1: { firstName: "Jeffrey", lastName: "Lebowski" },
    2: { firstName: "Walter", lastName: "Sobchak" },
    };
    });

    describe("with vanilla JS spread operator", () => {
    it("returns the expected results", () => {
    // if the key is a string we can skip type casting to string
    // const { [deleteId]: deleted, ...result } = characters;
    const { [`${deleteId}`]: deleted, ...result } = characters;
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with vanilla JS reduce", () => {
    it("returns the expected results", () => {
    const result = Object.keys(characters).reduce((newObj, id) => {
    if (id !== `${deleteId}`) {
    return { ...newObj, [id]: characters[id] };
    }
    return newObj;
    }, {});
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with lodhash omit", () => {
    it("returns the expected results", () => {
    // note that we can pass in an integer key here and it handles it without needing to type cast
    const result = _.omit(characters, deleteId);
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with Ramda omit", () => {
    it("returns the expected results", () => {
    // can't pass in an integer key here so we need to type cast it to a string
    const result = R.omit(`${deleteId}`, characters);
    expect(result).toEqual(expectedResult);
    });
    });

    describe("with Immutable.js", () => {
    it("returns the expected results", () => {
    const immutableCharacters = Map(characters);
    // can't pass in an integer key here so we need to type cast it to a string
    const result = immutableCharacters.delete(`${deleteId}`);
    expect(result.toObject()).toEqual(expectedResult);
    });
    });
    });
    });