From 623f972271e4389ba6d4beb550f1554f9daf7632 Mon Sep 17 00:00:00 2001 From: James Donnelly <4444684+JDIZM@users.noreply.github.com> Date: Mon, 19 Jun 2023 15:23:16 +0100 Subject: [PATCH 01/11] test: rename test desc and sort --- src/helpers/sort.test.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/helpers/sort.test.ts b/src/helpers/sort.test.ts index 31e54bd..d197de4 100644 --- a/src/helpers/sort.test.ts +++ b/src/helpers/sort.test.ts @@ -36,6 +36,7 @@ describe("array sort", () => { const result = array.sort((a, b) => defaultCompare(a, b)); expect(result).toEqual(["a", "ab", "ac", "ae", "ag", "ba", "z"]); }); + it("should sort an array of strings that are numbers", () => { const array = ["5", "4", "3", "2", "1"]; const result = array.sort((a, b) => defaultCompare(a, b)); @@ -44,12 +45,13 @@ describe("array sort", () => { }); describe("sortProducts", () => { - it("should sort an array of products by pick location", () => { + it("should sort an array of products by pick location in ascending order from A 1 to A 10", () => { const data: ProductTuple[] = [ ["product_code", "quantity", "pick_location"], - ["B1234", "2", "A3"], - ["B1235", "3", "A2"], - ["B1236", "4", "A1"] + ["B1237", "2", "A 10"], + ["B1234", "2", "A 3"], + ["B1235", "3", "A 2"], + ["B1236", "4", "A 1"] ]; const [columns, ...rows] = data; @@ -58,12 +60,13 @@ describe("sortProducts", () => { expect(result).toEqual([ ["product_code", "quantity", "pick_location"], - ["B1236", "4", "A1"], - ["B1235", "3", "A2"], - ["B1234", "2", "A3"] + ["B1236", "4", "A 1"], + ["B1235", "3", "A 2"], + ["B1234", "2", "A 3"], + ["B1237", "2", "A 10"] ]); }); - it("should sort an array of products by bay and shelf height in ascending order", () => { + it("should sort an array of products by pick location (bay and shelf height) in ascending order", () => { const data: ProductTuple[] = [ ["product_code", "quantity", "pick_location"], ["A", "10", "Z 1"], From 440f514e150170b6fabce14f5e9eb007a69d8916 Mon Sep 17 00:00:00 2001 From: James Donnelly <4444684+JDIZM@users.noreply.github.com> Date: Mon, 19 Jun 2023 23:35:25 +0100 Subject: [PATCH 02/11] feat(wip): created a new sort function --- src/helpers/sort.test.ts | 96 +++++++++++++++++++++++++++++++++++++++- src/helpers/sort.ts | 39 ++++++++++++++++ 2 files changed, 134 insertions(+), 1 deletion(-) diff --git a/src/helpers/sort.test.ts b/src/helpers/sort.test.ts index d197de4..d1a7590 100644 --- a/src/helpers/sort.test.ts +++ b/src/helpers/sort.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from "vitest"; -import { swap, defaultCompare, sortProducts, ProductTuple } from "./sort"; +import { swap, defaultCompare, sortProducts, ProductTuple, newSortProducts } from "./sort"; describe("swap", () => { it("should swap two items in an array", () => { @@ -108,4 +108,98 @@ describe("sortProducts", () => { ["F", "1", "AB 10"] ]); }); + + it("should sort by shelf height if the bays are not the same", () => { + const data: ProductTuple[] = [ + ["product_code", "quantity", "pick_location"], + ["B1237", "2", "A 10"], + ["B1237", "2", "Z 10"], + ["B1234", "2", "Z 3"], + ["B1234", "2", "A 3"], + ["B1235", "3", "Z 2"], + ["B1236", "4", "Z 1"], + ["B1235", "3", "A 2"], + ["B1236", "4", "A 1"] + ]; + + const [columns, ...rows] = data; + + const sortedRows = sortProducts(rows); + const result = [columns, ...sortedRows]; + expect(result).toEqual([ + ["product_code", "quantity", "pick_location"], + ["B1236", "4", "A 1"], + ["B1235", "3", "A 2"], + ["B1234", "2", "A 3"], + ["B1237", "2", "A 10"], + ["B1236", "4", "Z 1"], + ["B1235", "3", "Z 2"], + ["B1234", "2", "Z 3"], + ["B1237", "2", "Z 10"] + ]); + }); +}); + +describe("new sort products", () => { + // TODO a to az + const data: ProductTuple[] = [ + ["product_code", "quantity", "pick_location"], + ["1", "1", "AB 1"], + ["2", "1", "AB 10"], + ["3", "1", "AB 9"], + ["4", "1", "AB 7"] + ]; + // it("should throw an error if the pick location is invalid", () => { + // // + // // const [columns, ...rows] = data; + // // const result = newSortProducts(rows, "ascending"); + // // // console.log(''); + // // console.log("result", result); + // }); + + it("should correctly split a pick location into bay and shelf height", () => { + // + }); + + it("should sort products with the same bay by shelf height", () => { + const [, ...rows] = data; + const result = newSortProducts(rows, "ascending"); + expect(result).toEqual([ + ["1", "1", "AB 1"], + ["4", "1", "AB 7"], + ["3", "1", "AB 9"], + ["2", "1", "AB 10"] + ]); + }); + + it("should sort products that do not have the same bay by bay and then by shelf height", () => { + const data: ProductTuple[] = [ + ["product_code", "quantity", "pick_location"], + // ["1", "1", "A 1"], + // ["2", "1", "Z 1"], + ["3", "1", "AB 10"], + ["4", "1", "AB 9"], + ["5", "1", "AB 7"], + ["6", "1", "AZ 1"], + ["7", "1", "AZ 10"], + ["8", "1", "AZ 9"], + ["9", "1", "AZ 7"] + ]; + const [, ...rows] = data; + const result = newSortProducts(rows, "ascending"); + console.log("result", result); + expect(result).toEqual([ + ["5", "1", "AB 7"], + ["4", "1", "AB 9"], + ["3", "1", "AB 10"], + ["6", "1", "AZ 1"], + ["9", "1", "AZ 7"], + ["8", "1", "AZ 9"], + ["7", "1", "AZ 10"] + ]); + }); + + it("should sort an array of products by pick location in ascending order from A 1 to AZ 10", () => { + // + }); }); diff --git a/src/helpers/sort.ts b/src/helpers/sort.ts index f7aba00..77d99b9 100644 --- a/src/helpers/sort.ts +++ b/src/helpers/sort.ts @@ -37,3 +37,42 @@ export const sortProducts = (products: ProductTuple[]) => { products.sort(sortByPickLocation); return products; }; + +type SortMethod = "ascending" | "descending"; + +export const newSortProducts = (products: ProductTuple[], method: SortMethod) => { + const result = [...products]; + console.log("method", method); + + for (let p = 0; p < result.length; p++) { + // iterate over products + console.log("product", result[p]); + for (let i = 0; i < result.length; i++) { + // sort each product by pick location + // console.log("i", i); + const currentProduct = result[i]; + const nextProduct = result[i + 1]; + console.log(currentProduct, nextProduct); + if (!nextProduct) { + break; + } + const [, , currentPickLocation] = currentProduct; + const [, , nextPickLocation] = nextProduct; + const [currentBay, currentShelf] = currentPickLocation.split(" "); + const [nextBay, nextShelf] = nextPickLocation.split(" "); + + if (currentBay === nextBay) { + // console.log("same bay"); + if (Number(currentShelf) > Number(nextShelf)) { + swap(result, i, i + 1); + } + } + + if (currentBay > nextBay) { + swap(result, i, i + 1); + } + } + } + + return result; +}; From 6e7194c21ad2c396b71cbd4c8c49ab97909fe7fd Mon Sep 17 00:00:00 2001 From: James Donnelly <4444684+JDIZM@users.noreply.github.com> Date: Mon, 19 Jun 2023 23:42:00 +0100 Subject: [PATCH 03/11] feat(wip): reverse array when method is descending --- src/helpers/sort.test.ts | 11 +++++++++++ src/helpers/sort.ts | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/src/helpers/sort.test.ts b/src/helpers/sort.test.ts index d1a7590..7232fce 100644 --- a/src/helpers/sort.test.ts +++ b/src/helpers/sort.test.ts @@ -202,4 +202,15 @@ describe("new sort products", () => { it("should sort an array of products by pick location in ascending order from A 1 to AZ 10", () => { // }); + + it('should reverse the results if the method is "descending"', () => { + const [, ...rows] = data; + const result = newSortProducts(rows, "descending"); + expect(result).toEqual([ + ["2", "1", "AB 10"], + ["3", "1", "AB 9"], + ["4", "1", "AB 7"], + ["1", "1", "AB 1"] + ]); + }); }); diff --git a/src/helpers/sort.ts b/src/helpers/sort.ts index 77d99b9..4dc55ba 100644 --- a/src/helpers/sort.ts +++ b/src/helpers/sort.ts @@ -74,5 +74,9 @@ export const newSortProducts = (products: ProductTuple[], method: SortMethod) => } } + if (method === "descending") { + result.reverse(); + } + return result; }; From c65072a274a3b4031a47c4f34190ee3528f45d7e Mon Sep 17 00:00:00 2001 From: James Donnelly <4444684+JDIZM@users.noreply.github.com> Date: Tue, 20 Jun 2023 00:28:28 +0100 Subject: [PATCH 04/11] feat(wip): filter duplicates and add qty with map function --- src/helpers/sort.test.ts | 41 +++++++++++++++++++++++++--------- src/helpers/sort.ts | 48 ++++++++++++++++++++++++++++++++++------ 2 files changed, 71 insertions(+), 18 deletions(-) diff --git a/src/helpers/sort.test.ts b/src/helpers/sort.test.ts index 7232fce..dd40bb0 100644 --- a/src/helpers/sort.test.ts +++ b/src/helpers/sort.test.ts @@ -172,6 +172,36 @@ describe("new sort products", () => { ]); }); + it('should reverse the results if the method is "descending"', () => { + const [, ...rows] = data; + const result = newSortProducts(rows, "descending"); + expect(result).toEqual([ + ["2", "1", "AB 10"], + ["3", "1", "AB 9"], + ["4", "1", "AB 7"], + ["1", "1", "AB 1"] + ]); + }); + + it("should deduplicate products by id and add their qty", () => { + const data: ProductTuple[] = [ + ["product_code", "quantity", "pick_location"], + ["1", "1", "AB 1"], + ["1", "1", "AB 1"], + ["2", "1", "AB 10"], + ["3", "1", "AB 9"], + ["4", "1", "AB 7"] + ]; + const [, ...rows] = data; + const result = newSortProducts(rows, "descending"); + expect(result).toEqual([ + ["2", "1", "AB 10"], + ["3", "1", "AB 9"], + ["4", "1", "AB 7"], + ["1", "2", "AB 1"] + ]); + }); + it("should sort products that do not have the same bay by bay and then by shelf height", () => { const data: ProductTuple[] = [ ["product_code", "quantity", "pick_location"], @@ -202,15 +232,4 @@ describe("new sort products", () => { it("should sort an array of products by pick location in ascending order from A 1 to AZ 10", () => { // }); - - it('should reverse the results if the method is "descending"', () => { - const [, ...rows] = data; - const result = newSortProducts(rows, "descending"); - expect(result).toEqual([ - ["2", "1", "AB 10"], - ["3", "1", "AB 9"], - ["4", "1", "AB 7"], - ["1", "1", "AB 1"] - ]); - }); }); diff --git a/src/helpers/sort.ts b/src/helpers/sort.ts index 4dc55ba..0eb624f 100644 --- a/src/helpers/sort.ts +++ b/src/helpers/sort.ts @@ -40,29 +40,55 @@ export const sortProducts = (products: ProductTuple[]) => { type SortMethod = "ascending" | "descending"; +const filterProductsById = (products: ProductTuple[]) => { + const productsMap = new Map(); + + for (let p = 0; p < products.length; p++) { + const product = products[p]; + const [id] = product; + + if (productsMap.has(id)) { + const existingProduct = productsMap.get(id); + + if (existingProduct?.length === 3) { + const [, existingQty] = existingProduct; + const [, qty] = product; + existingProduct[1] = String(Number(existingQty) + Number(qty)); + productsMap.set(id, existingProduct); + } + continue; + } + productsMap.set(id, product); + } + + return [...productsMap.values()]; +}; + export const newSortProducts = (products: ProductTuple[], method: SortMethod) => { - const result = [...products]; - console.log("method", method); + const filtered = filterProductsById(products); + const result = [...filtered]; + + for (let p = 0; p < products.length; p++) { + // iterate over products and check for uniques + const product = products[p]; + const [id] = product; - for (let p = 0; p < result.length; p++) { - // iterate over products - console.log("product", result[p]); for (let i = 0; i < result.length; i++) { // sort each product by pick location - // console.log("i", i); const currentProduct = result[i]; const nextProduct = result[i + 1]; console.log(currentProduct, nextProduct); + if (!nextProduct) { break; } + const [, , currentPickLocation] = currentProduct; const [, , nextPickLocation] = nextProduct; const [currentBay, currentShelf] = currentPickLocation.split(" "); const [nextBay, nextShelf] = nextPickLocation.split(" "); if (currentBay === nextBay) { - // console.log("same bay"); if (Number(currentShelf) > Number(nextShelf)) { swap(result, i, i + 1); } @@ -71,6 +97,14 @@ export const newSortProducts = (products: ProductTuple[], method: SortMethod) => if (currentBay > nextBay) { swap(result, i, i + 1); } + + if (currentBay < nextBay) { + continue; + } + + // if currentBay is more than one letter eg AZ not A + // then sort by the first letter + // then sort by the second letter } } From ec776e3d3b0ec0722e924ff405ded9ed98da67f3 Mon Sep 17 00:00:00 2001 From: James Donnelly <4444684+JDIZM@users.noreply.github.com> Date: Tue, 20 Jun 2023 15:17:06 +0100 Subject: [PATCH 05/11] feat(wip): added a new string compare function --- src/helpers/sort.test.ts | 123 ++++++++++++++++++++++++++++++++++++++- src/helpers/sort.ts | 98 ++++++++++++++++++++++++++----- 2 files changed, 202 insertions(+), 19 deletions(-) diff --git a/src/helpers/sort.test.ts b/src/helpers/sort.test.ts index dd40bb0..d1d0f19 100644 --- a/src/helpers/sort.test.ts +++ b/src/helpers/sort.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from "vitest"; -import { swap, defaultCompare, sortProducts, ProductTuple, newSortProducts } from "./sort"; +import { swap, defaultCompare, sortProducts, ProductTuple, newSortProducts, compareStrings, Compare } from "./sort"; describe("swap", () => { it("should swap two items in an array", () => { @@ -217,7 +217,6 @@ describe("new sort products", () => { ]; const [, ...rows] = data; const result = newSortProducts(rows, "ascending"); - console.log("result", result); expect(result).toEqual([ ["5", "1", "AB 7"], ["4", "1", "AB 9"], @@ -230,6 +229,124 @@ describe("new sort products", () => { }); it("should sort an array of products by pick location in ascending order from A 1 to AZ 10", () => { - // + const data: ProductTuple[] = [ + ["product_code", "quantity", "pick_location"], + ["1", "1", "A 1"], + ["2", "1", "Z 1"], + ["3", "1", "AB 10"], + ["9", "1", "AZ 7"] + ]; + const [, ...rows] = data; + const result = newSortProducts(rows, "ascending"); + console.log("result", result); + expect(result).toEqual([ + ["1", "1", "A 1"], + ["2", "1", "Z 1"], + ["3", "1", "AB 10"], + ["9", "1", "AZ 7"] + ]); }); }); + +describe("compareStrings", () => { + // it("should return undefined if nothing matches", () => { + // // TODO empty case + // }); + describe("single char", () => { + // Case 1: A, A - single chars, both match + it("should return EQUALS if single chars, both match", () => { + const data = ["A", "A"]; + const result = compareStrings(data[0], data[1]); + expect(result).toEqual(Compare.EQUALS); + }); + + // Case 2: A, Z || Z, A - single chars, no match + it("should return BIGGER THAN if single chars, no match", () => { + const data = ["Z", "A"]; + const result = compareStrings(data[0], data[1]); + expect(result).toEqual(Compare.BIGGER_THAN); + }); + + it("should return LESS THAN if single chars, no match", () => { + const data = ["A", "Z"]; + const result = compareStrings(data[0], data[1]); + expect(result).toEqual(Compare.LESS_THAN); + }); + }); + + describe("multiple chars", () => { + // Case 3: AA, AA - multiple chars, both match + it("should return EQUALS if the first and second letters are the same", () => { + const data = ["AA", "AA"]; + const result = compareStrings(data[0], data[1]); + expect(result).toEqual(Compare.EQUALS); + }); + + // Case 4: AA, AZ - multiple chars, only first letters match + it("should return LESS THAN if the first letters match but the second char is lower", () => { + const data = ["AA", "AB"]; + const result = compareStrings(data[0], data[1]); + expect(result).toEqual(Compare.LESS_THAN); + }); + + it("should return BIGGER THAN if the first letters match but the second char is higher", () => { + const data = ["AB", "AA"]; + const result = compareStrings(data[0], data[1]); + expect(result).toEqual(Compare.BIGGER_THAN); + }); + + // Case 5: ZA, AA - multiple chars, only second letters match + it("should return LESS THAN if the first letters dont match and only second letters match", () => { + const data = ["AA", "BA"]; + const result = compareStrings(data[0], data[1]); + expect(result).toEqual(Compare.LESS_THAN); + }); + + it("should return BIGGER THAN if the first letters dont match and only second letters match", () => { + const data = ["BA", "AA"]; + const result = compareStrings(data[0], data[1]); + expect(result).toEqual(Compare.BIGGER_THAN); + }); + + // Case 6: ZA, AZ - multiple chars, no match + it("should return BIGGER THAN if no chars match and the first char is lower", () => { + const data = [ + ["ZA", "AZ"], + ["XY", "AK"] + ]; + data.forEach(([a, b]) => { + const result = compareStrings(a, b); + expect(result).toEqual(Compare.BIGGER_THAN); + }); + }); + + it("should return LESS THAN if no chars match and the first char is higher", () => { + const data = [ + ["AZ", "ZA"], + ["KA", "XY"] + ]; + data.forEach(([a, b]) => { + const result = compareStrings(a, b); + expect(result).toEqual(Compare.LESS_THAN); + }); + }); + + // Case 7: AA, Z - multiple chars, and single char + it("should return LESS THAN if the first string is multiple chars and the second is a single char", () => { + const data = ["AA", "Z"]; + const result = compareStrings(data[0], data[1]); + expect(result).toEqual(Compare.LESS_THAN); + }); + + // Case 8: Z, AA - single char, and multiple chars + it("should return BIGGER THAN if the first string is a single char and second is multiple", () => { + const data = ["Z", "AA"]; + const result = compareStrings(data[0], data[1]); + expect(result).toEqual(Compare.BIGGER_THAN); + }); + }); + + // describe("numeric shelf height", () => { + // // + // }); +}); diff --git a/src/helpers/sort.ts b/src/helpers/sort.ts index 0eb624f..2b92765 100644 --- a/src/helpers/sort.ts +++ b/src/helpers/sort.ts @@ -1,4 +1,4 @@ -const Compare = { +export const Compare = { LESS_THAN: -1, BIGGER_THAN: 1, EQUALS: 0 @@ -64,20 +64,78 @@ const filterProductsById = (products: ProductTuple[]) => { return [...productsMap.values()]; }; +export const compareStrings = (a: string, b: string) => { + // Always comparing a to b + + // Single chars + // Case 1: A, A - single chars, both match + // Case 2: A, Z || Z, A - single chars, no match + + // Multiple chars + // Case 3: AA, AA - multiple chars, both match + // Case 4: AA, AZ - multiple chars, only first letters match + // Case 5: ZA, AA - multiple chars, only second letters match + // Case 6: ZA, AZ - multiple chars, no match + + // Case 7: AA, Z - multiple chars, and single char + // Case 8: Z, AA - single char, and multiple chars + + if (a.length === 1 && b.length === 1) { + // Case 1: A, A - single chars, both match + if (a === b) { + return Compare.EQUALS; + } + // Case 2: A, Z || Z, A - single chars, no match + return a < b ? Compare.LESS_THAN : Compare.BIGGER_THAN; + } + + if (a.length > 1 && b.length > 1) { + const [firstLetterA, secondLetterA] = a.split(""); + const [firstLetterB, secondLetterB] = b.split(""); + + if (firstLetterA === firstLetterB) { + if (secondLetterA === secondLetterB) { + // Case 3: AA, AA - multiple chars, both match + return Compare.EQUALS; + } + + // Case 4: AA, AZ - multiple chars, only first letters match + return secondLetterA < secondLetterB ? Compare.LESS_THAN : Compare.BIGGER_THAN; + } + + // Case 6: ZA, AZ - multiple chars, no match + if (firstLetterA !== firstLetterB && secondLetterA !== secondLetterB) { + return firstLetterA < firstLetterB ? Compare.LESS_THAN : Compare.BIGGER_THAN; + } + + // Case 5: ZA, AA - multiple chars, only second letters match + return firstLetterA < firstLetterB ? Compare.LESS_THAN : Compare.BIGGER_THAN; + } + + // Case 7: AA, Z - multiple chars, and single char + if (a.length > 1 && b.length === 1) { + return Compare.LESS_THAN; + } + + // Case 8: Z, AA - single char, and multiple chars + if (a.length === 1 && b.length > 1) { + return Compare.BIGGER_THAN; + } + + // TODO default case and return value + return undefined; +}; + export const newSortProducts = (products: ProductTuple[], method: SortMethod) => { - const filtered = filterProductsById(products); - const result = [...filtered]; + const result = filterProductsById(products); for (let p = 0; p < products.length; p++) { - // iterate over products and check for uniques - const product = products[p]; - const [id] = product; + // iterate over products for (let i = 0; i < result.length; i++) { // sort each product by pick location const currentProduct = result[i]; const nextProduct = result[i + 1]; - console.log(currentProduct, nextProduct); if (!nextProduct) { break; @@ -88,18 +146,26 @@ export const newSortProducts = (products: ProductTuple[], method: SortMethod) => const [currentBay, currentShelf] = currentPickLocation.split(" "); const [nextBay, nextShelf] = nextPickLocation.split(" "); - if (currentBay === nextBay) { - if (Number(currentShelf) > Number(nextShelf)) { - swap(result, i, i + 1); + // TODO refactor this for multiple letters + if (currentBay.length === 1 || currentBay.length > 1) { + console.log("equal", currentBay, nextBay); + + // top of the sort order + if (currentBay < nextBay) { + continue; } - } - if (currentBay > nextBay) { - swap(result, i, i + 1); - } + // swap based on shelf + if (currentBay === nextBay) { + if (Number(currentShelf) > Number(nextShelf)) { + swap(result, i, i + 1); + } + } - if (currentBay < nextBay) { - continue; + // swap based on bay + if (currentBay > nextBay) { + swap(result, i, i + 1); + } } // if currentBay is more than one letter eg AZ not A From 78acbdb9fabb82c041f8f0fb85e198e0b242185a Mon Sep 17 00:00:00 2001 From: James Donnelly <4444684+JDIZM@users.noreply.github.com> Date: Tue, 20 Jun 2023 16:19:14 +0100 Subject: [PATCH 06/11] feat(wip): working compare --- src/helpers/sort.test.ts | 281 +++++++++++++++++++-------------------- src/helpers/sort.ts | 77 +++++------ 2 files changed, 175 insertions(+), 183 deletions(-) diff --git a/src/helpers/sort.test.ts b/src/helpers/sort.test.ts index d1d0f19..46fad93 100644 --- a/src/helpers/sort.test.ts +++ b/src/helpers/sort.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from "vitest"; -import { swap, defaultCompare, sortProducts, ProductTuple, newSortProducts, compareStrings, Compare } from "./sort"; +import { swap, ProductTuple, sortProducts, compareStrings, Compare } from "./sort"; describe("swap", () => { it("should swap two items in an array", () => { @@ -9,138 +9,138 @@ describe("swap", () => { }); }); -describe("defaultCompare", () => { - it("should return -1 if a < b", () => { - const result = defaultCompare(1, 2); - expect(result).toBe(-1); - }); - it("should return 1 if a > b", () => { - const result = defaultCompare(2, 1); - expect(result).toBe(1); - }); - it("should return 0 if a === b", () => { - const result = defaultCompare(1, 1); - expect(result).toBe(0); - }); -}); - -describe("array sort", () => { - it("should sort an array of numbers", () => { - const array = [4, 2, 3, 1, 5]; - const result = array.sort((a, b) => defaultCompare(a, b)); - expect(result).toEqual([1, 2, 3, 4, 5]); - }); - - it("should sort an array of strings", () => { - const array = ["a", "z", "ag", "ac", "ab", "ae", "ba"]; - const result = array.sort((a, b) => defaultCompare(a, b)); - expect(result).toEqual(["a", "ab", "ac", "ae", "ag", "ba", "z"]); - }); - - it("should sort an array of strings that are numbers", () => { - const array = ["5", "4", "3", "2", "1"]; - const result = array.sort((a, b) => defaultCompare(a, b)); - expect(result).toEqual(["1", "2", "3", "4", "5"]); - }); -}); +// describe("defaultCompare", () => { +// it("should return -1 if a < b", () => { +// const result = defaultCompare(1, 2); +// expect(result).toBe(-1); +// }); +// it("should return 1 if a > b", () => { +// const result = defaultCompare(2, 1); +// expect(result).toBe(1); +// }); +// it("should return 0 if a === b", () => { +// const result = defaultCompare(1, 1); +// expect(result).toBe(0); +// }); +// }); + +// describe("array sort", () => { +// it("should sort an array of numbers", () => { +// const array = [4, 2, 3, 1, 5]; +// const result = array.sort((a, b) => defaultCompare(a, b)); +// expect(result).toEqual([1, 2, 3, 4, 5]); +// }); + +// it("should sort an array of strings", () => { +// const array = ["a", "z", "ag", "ac", "ab", "ae", "ba"]; +// const result = array.sort((a, b) => defaultCompare(a, b)); +// expect(result).toEqual(["a", "ab", "ac", "ae", "ag", "ba", "z"]); +// }); + +// it("should sort an array of strings that are numbers", () => { +// const array = ["5", "4", "3", "2", "1"]; +// const result = array.sort((a, b) => defaultCompare(a, b)); +// expect(result).toEqual(["1", "2", "3", "4", "5"]); +// }); +// }); + +// describe("sortProducts", () => { +// it("should sort an array of products by pick location in ascending order from A 1 to A 10", () => { +// const data: ProductTuple[] = [ +// ["product_code", "quantity", "pick_location"], +// ["B1237", "2", "A 10"], +// ["B1234", "2", "A 3"], +// ["B1235", "3", "A 2"], +// ["B1236", "4", "A 1"] +// ]; +// const [columns, ...rows] = data; + +// const sortedRows = sortProducts(rows); +// const result = [columns, ...sortedRows]; + +// expect(result).toEqual([ +// ["product_code", "quantity", "pick_location"], +// ["B1236", "4", "A 1"], +// ["B1235", "3", "A 2"], +// ["B1234", "2", "A 3"], +// ["B1237", "2", "A 10"] +// ]); +// }); +// it("should sort an array of products by pick location (bay and shelf height) in ascending order", () => { +// const data: ProductTuple[] = [ +// ["product_code", "quantity", "pick_location"], +// ["A", "10", "Z 1"], +// ["B", "5", "Z 10"], +// ["C", "10", "A 1"], +// ["G", "1", "A 7"] +// ]; +// const [columns, ...rows] = data; + +// const sortedRows = sortProducts(rows); +// const result = [columns, ...sortedRows]; + +// expect(result).toEqual([ +// ["product_code", "quantity", "pick_location"], +// ["C", "10", "A 1"], +// ["G", "1", "A 7"], +// ["A", "10", "Z 1"], +// ["B", "5", "Z 10"] +// ]); +// }); +// it("should sort an array of products by bay and shelf height in ascending order WHEN bays are the same FROM lowest to highest shelf", () => { +// const data: ProductTuple[] = [ +// ["product_code", "quantity", "pick_location"], +// ["E", "1", "AB 1"], +// ["F", "1", "AB 10"], +// ["H", "1", "AB 9"], +// ["H", "1", "AB 7"] +// ]; +// const [columns, ...rows] = data; + +// const sortedRows = sortProducts(rows); +// const result = [columns, ...sortedRows]; + +// expect(result).toEqual([ +// ["product_code", "quantity", "pick_location"], +// ["E", "1", "AB 1"], +// ["H", "1", "AB 7"], +// ["H", "1", "AB 9"], +// ["F", "1", "AB 10"] +// ]); +// }); + +// it("should sort by shelf height if the bays are not the same", () => { +// const data: ProductTuple[] = [ +// ["product_code", "quantity", "pick_location"], +// ["B1237", "2", "A 10"], +// ["B1237", "2", "Z 10"], +// ["B1234", "2", "Z 3"], +// ["B1234", "2", "A 3"], +// ["B1235", "3", "Z 2"], +// ["B1236", "4", "Z 1"], +// ["B1235", "3", "A 2"], +// ["B1236", "4", "A 1"] +// ]; + +// const [columns, ...rows] = data; + +// const sortedRows = sortProducts(rows); +// const result = [columns, ...sortedRows]; +// expect(result).toEqual([ +// ["product_code", "quantity", "pick_location"], +// ["B1236", "4", "A 1"], +// ["B1235", "3", "A 2"], +// ["B1234", "2", "A 3"], +// ["B1237", "2", "A 10"], +// ["B1236", "4", "Z 1"], +// ["B1235", "3", "Z 2"], +// ["B1234", "2", "Z 3"], +// ["B1237", "2", "Z 10"] +// ]); +// }); +// }); describe("sortProducts", () => { - it("should sort an array of products by pick location in ascending order from A 1 to A 10", () => { - const data: ProductTuple[] = [ - ["product_code", "quantity", "pick_location"], - ["B1237", "2", "A 10"], - ["B1234", "2", "A 3"], - ["B1235", "3", "A 2"], - ["B1236", "4", "A 1"] - ]; - const [columns, ...rows] = data; - - const sortedRows = sortProducts(rows); - const result = [columns, ...sortedRows]; - - expect(result).toEqual([ - ["product_code", "quantity", "pick_location"], - ["B1236", "4", "A 1"], - ["B1235", "3", "A 2"], - ["B1234", "2", "A 3"], - ["B1237", "2", "A 10"] - ]); - }); - it("should sort an array of products by pick location (bay and shelf height) in ascending order", () => { - const data: ProductTuple[] = [ - ["product_code", "quantity", "pick_location"], - ["A", "10", "Z 1"], - ["B", "5", "Z 10"], - ["C", "10", "A 1"], - ["G", "1", "A 7"] - ]; - const [columns, ...rows] = data; - - const sortedRows = sortProducts(rows); - const result = [columns, ...sortedRows]; - - expect(result).toEqual([ - ["product_code", "quantity", "pick_location"], - ["C", "10", "A 1"], - ["G", "1", "A 7"], - ["A", "10", "Z 1"], - ["B", "5", "Z 10"] - ]); - }); - it("should sort an array of products by bay and shelf height in ascending order WHEN bays are the same FROM lowest to highest shelf", () => { - const data: ProductTuple[] = [ - ["product_code", "quantity", "pick_location"], - ["E", "1", "AB 1"], - ["F", "1", "AB 10"], - ["H", "1", "AB 9"], - ["H", "1", "AB 7"] - ]; - const [columns, ...rows] = data; - - const sortedRows = sortProducts(rows); - const result = [columns, ...sortedRows]; - - expect(result).toEqual([ - ["product_code", "quantity", "pick_location"], - ["E", "1", "AB 1"], - ["H", "1", "AB 7"], - ["H", "1", "AB 9"], - ["F", "1", "AB 10"] - ]); - }); - - it("should sort by shelf height if the bays are not the same", () => { - const data: ProductTuple[] = [ - ["product_code", "quantity", "pick_location"], - ["B1237", "2", "A 10"], - ["B1237", "2", "Z 10"], - ["B1234", "2", "Z 3"], - ["B1234", "2", "A 3"], - ["B1235", "3", "Z 2"], - ["B1236", "4", "Z 1"], - ["B1235", "3", "A 2"], - ["B1236", "4", "A 1"] - ]; - - const [columns, ...rows] = data; - - const sortedRows = sortProducts(rows); - const result = [columns, ...sortedRows]; - expect(result).toEqual([ - ["product_code", "quantity", "pick_location"], - ["B1236", "4", "A 1"], - ["B1235", "3", "A 2"], - ["B1234", "2", "A 3"], - ["B1237", "2", "A 10"], - ["B1236", "4", "Z 1"], - ["B1235", "3", "Z 2"], - ["B1234", "2", "Z 3"], - ["B1237", "2", "Z 10"] - ]); - }); -}); - -describe("new sort products", () => { // TODO a to az const data: ProductTuple[] = [ ["product_code", "quantity", "pick_location"], @@ -163,7 +163,7 @@ describe("new sort products", () => { it("should sort products with the same bay by shelf height", () => { const [, ...rows] = data; - const result = newSortProducts(rows, "ascending"); + const result = sortProducts(rows, "ascending"); expect(result).toEqual([ ["1", "1", "AB 1"], ["4", "1", "AB 7"], @@ -174,7 +174,7 @@ describe("new sort products", () => { it('should reverse the results if the method is "descending"', () => { const [, ...rows] = data; - const result = newSortProducts(rows, "descending"); + const result = sortProducts(rows, "descending"); expect(result).toEqual([ ["2", "1", "AB 10"], ["3", "1", "AB 9"], @@ -193,7 +193,7 @@ describe("new sort products", () => { ["4", "1", "AB 7"] ]; const [, ...rows] = data; - const result = newSortProducts(rows, "descending"); + const result = sortProducts(rows, "descending"); expect(result).toEqual([ ["2", "1", "AB 10"], ["3", "1", "AB 9"], @@ -216,7 +216,7 @@ describe("new sort products", () => { ["9", "1", "AZ 7"] ]; const [, ...rows] = data; - const result = newSortProducts(rows, "ascending"); + const result = sortProducts(rows, "ascending"); expect(result).toEqual([ ["5", "1", "AB 7"], ["4", "1", "AB 9"], @@ -237,8 +237,7 @@ describe("new sort products", () => { ["9", "1", "AZ 7"] ]; const [, ...rows] = data; - const result = newSortProducts(rows, "ascending"); - console.log("result", result); + const result = sortProducts(rows, "ascending"); expect(result).toEqual([ ["1", "1", "A 1"], ["2", "1", "Z 1"], @@ -332,17 +331,17 @@ describe("compareStrings", () => { }); // Case 7: AA, Z - multiple chars, and single char - it("should return LESS THAN if the first string is multiple chars and the second is a single char", () => { + it("should return BIGGER THAN if the first string is multiple chars and the second is a single char", () => { const data = ["AA", "Z"]; const result = compareStrings(data[0], data[1]); - expect(result).toEqual(Compare.LESS_THAN); + expect(result).toEqual(Compare.BIGGER_THAN); }); // Case 8: Z, AA - single char, and multiple chars - it("should return BIGGER THAN if the first string is a single char and second is multiple", () => { + it("should return LESS THAN if the first string is a single char and second is multiple", () => { const data = ["Z", "AA"]; const result = compareStrings(data[0], data[1]); - expect(result).toEqual(Compare.BIGGER_THAN); + expect(result).toEqual(Compare.LESS_THAN); }); }); diff --git a/src/helpers/sort.ts b/src/helpers/sort.ts index 2b92765..5594fdd 100644 --- a/src/helpers/sort.ts +++ b/src/helpers/sort.ts @@ -8,12 +8,12 @@ type Compare = (typeof Compare)[keyof typeof Compare]; export type ProductTuple = [string, string, string]; -export const defaultCompare = (a: string | number, b: string | number): Compare => { - if (a === b) { - return Compare.EQUALS; - } - return a < b ? Compare.LESS_THAN : Compare.BIGGER_THAN; -}; +// export const defaultCompare = (a: string | number, b: string | number): Compare => { +// if (a === b) { +// return Compare.EQUALS; +// } +// return a < b ? Compare.LESS_THAN : Compare.BIGGER_THAN; +// }; export const swap = (array: unknown[], a: number, b: number) => { const temp = array[a]; @@ -21,22 +21,22 @@ export const swap = (array: unknown[], a: number, b: number) => { array[b] = temp; }; -export const sortProducts = (products: ProductTuple[]) => { - const sortByPickLocation = (a: ProductTuple, b: ProductTuple) => { - const [, , pickLocationA] = a; - const [, , pickLocationB] = b; - const [bayA, shelfA] = pickLocationA.split(" "); - const [bayB, shelfB] = pickLocationB.split(" "); +// export const sortProducts = (products: ProductTuple[]) => { +// const sortByPickLocation = (a: ProductTuple, b: ProductTuple) => { +// const [, , pickLocationA] = a; +// const [, , pickLocationB] = b; +// const [bayA, shelfA] = pickLocationA.split(" "); +// const [bayB, shelfB] = pickLocationB.split(" "); - if (bayA === bayB) { - return defaultCompare(Number(shelfA), Number(shelfB)); - } +// if (bayA === bayB) { +// return defaultCompare(Number(shelfA), Number(shelfB)); +// } - return defaultCompare(pickLocationA, pickLocationB); - }; - products.sort(sortByPickLocation); - return products; -}; +// return defaultCompare(pickLocationA, pickLocationB); +// }; +// products.sort(sortByPickLocation); +// return products; +// }; type SortMethod = "ascending" | "descending"; @@ -114,19 +114,19 @@ export const compareStrings = (a: string, b: string) => { // Case 7: AA, Z - multiple chars, and single char if (a.length > 1 && b.length === 1) { - return Compare.LESS_THAN; + return Compare.BIGGER_THAN; } // Case 8: Z, AA - single char, and multiple chars if (a.length === 1 && b.length > 1) { - return Compare.BIGGER_THAN; + return Compare.LESS_THAN; } // TODO default case and return value return undefined; }; -export const newSortProducts = (products: ProductTuple[], method: SortMethod) => { +export const sortProducts = (products: ProductTuple[], method: SortMethod) => { const result = filterProductsById(products); for (let p = 0; p < products.length; p++) { @@ -146,31 +146,24 @@ export const newSortProducts = (products: ProductTuple[], method: SortMethod) => const [currentBay, currentShelf] = currentPickLocation.split(" "); const [nextBay, nextShelf] = nextPickLocation.split(" "); - // TODO refactor this for multiple letters - if (currentBay.length === 1 || currentBay.length > 1) { - console.log("equal", currentBay, nextBay); - - // top of the sort order - if (currentBay < nextBay) { - continue; - } + const compare = compareStrings(currentBay, nextBay); - // swap based on shelf - if (currentBay === nextBay) { - if (Number(currentShelf) > Number(nextShelf)) { - swap(result, i, i + 1); - } - } + // top of the sort order + if (compare === Compare.LESS_THAN) { + continue; + } - // swap based on bay - if (currentBay > nextBay) { + // swap based on shelf if both match + if (compare === Compare.EQUALS) { + if (Number(currentShelf) > Number(nextShelf)) { swap(result, i, i + 1); } } - // if currentBay is more than one letter eg AZ not A - // then sort by the first letter - // then sort by the second letter + // swap based on bay + if (compare === Compare.BIGGER_THAN) { + swap(result, i, i + 1); + } } } From 5a26d13ddd56a53463bf2bf4fa35fe7b7a53e04f Mon Sep 17 00:00:00 2001 From: James Donnelly <4444684+JDIZM@users.noreply.github.com> Date: Tue, 20 Jun 2023 16:32:02 +0100 Subject: [PATCH 07/11] test: update tests and throw error if strings more than two chars --- src/helpers/sort.test.ts | 243 +++++++++++++++++---------------------- src/helpers/sort.ts | 12 +- 2 files changed, 114 insertions(+), 141 deletions(-) diff --git a/src/helpers/sort.test.ts b/src/helpers/sort.test.ts index 46fad93..dad45d8 100644 --- a/src/helpers/sort.test.ts +++ b/src/helpers/sort.test.ts @@ -9,139 +9,117 @@ describe("swap", () => { }); }); -// describe("defaultCompare", () => { -// it("should return -1 if a < b", () => { -// const result = defaultCompare(1, 2); -// expect(result).toBe(-1); -// }); -// it("should return 1 if a > b", () => { -// const result = defaultCompare(2, 1); -// expect(result).toBe(1); -// }); -// it("should return 0 if a === b", () => { -// const result = defaultCompare(1, 1); -// expect(result).toBe(0); -// }); -// }); - -// describe("array sort", () => { -// it("should sort an array of numbers", () => { -// const array = [4, 2, 3, 1, 5]; -// const result = array.sort((a, b) => defaultCompare(a, b)); -// expect(result).toEqual([1, 2, 3, 4, 5]); -// }); - -// it("should sort an array of strings", () => { -// const array = ["a", "z", "ag", "ac", "ab", "ae", "ba"]; -// const result = array.sort((a, b) => defaultCompare(a, b)); -// expect(result).toEqual(["a", "ab", "ac", "ae", "ag", "ba", "z"]); -// }); +describe("array sort", () => { + it("should sort an array of strings", () => { + const array = ["a", "z", "ag", "ac", "ab", "ae", "ba"]; + const result = array.sort((a, b) => compareStrings(a, b)); + expect(result).toEqual(["a", "z", "ab", "ac", "ae", "ag", "ba"]); + }); -// it("should sort an array of strings that are numbers", () => { -// const array = ["5", "4", "3", "2", "1"]; -// const result = array.sort((a, b) => defaultCompare(a, b)); -// expect(result).toEqual(["1", "2", "3", "4", "5"]); -// }); -// }); + it("should sort an array of strings that are numbers", () => { + const array = ["5", "4", "3", "2", "1"]; + const result = array.sort((a, b) => compareStrings(a, b)); + expect(result).toEqual(["1", "2", "3", "4", "5"]); + }); +}); -// describe("sortProducts", () => { -// it("should sort an array of products by pick location in ascending order from A 1 to A 10", () => { -// const data: ProductTuple[] = [ -// ["product_code", "quantity", "pick_location"], -// ["B1237", "2", "A 10"], -// ["B1234", "2", "A 3"], -// ["B1235", "3", "A 2"], -// ["B1236", "4", "A 1"] -// ]; -// const [columns, ...rows] = data; +describe("sortProducts", () => { + it("should sort an array of products by pick location in ascending order from A 1 to A 10", () => { + const data: ProductTuple[] = [ + ["product_code", "quantity", "pick_location"], + ["B1237", "2", "A 10"], + ["B1234", "2", "A 3"], + ["B1235", "3", "A 2"], + ["B1236", "4", "A 1"] + ]; + const [columns, ...rows] = data; -// const sortedRows = sortProducts(rows); -// const result = [columns, ...sortedRows]; + const sortedRows = sortProducts(rows, "ascending"); + const result = [columns, ...sortedRows]; -// expect(result).toEqual([ -// ["product_code", "quantity", "pick_location"], -// ["B1236", "4", "A 1"], -// ["B1235", "3", "A 2"], -// ["B1234", "2", "A 3"], -// ["B1237", "2", "A 10"] -// ]); -// }); -// it("should sort an array of products by pick location (bay and shelf height) in ascending order", () => { -// const data: ProductTuple[] = [ -// ["product_code", "quantity", "pick_location"], -// ["A", "10", "Z 1"], -// ["B", "5", "Z 10"], -// ["C", "10", "A 1"], -// ["G", "1", "A 7"] -// ]; -// const [columns, ...rows] = data; + expect(result).toEqual([ + ["product_code", "quantity", "pick_location"], + ["B1236", "4", "A 1"], + ["B1235", "3", "A 2"], + ["B1234", "2", "A 3"], + ["B1237", "2", "A 10"] + ]); + }); + it("should sort an array of products by pick location (bay and shelf height) in ascending order", () => { + const data: ProductTuple[] = [ + ["product_code", "quantity", "pick_location"], + ["A", "10", "Z 1"], + ["B", "5", "Z 10"], + ["C", "10", "A 1"], + ["G", "1", "A 7"] + ]; + const [columns, ...rows] = data; -// const sortedRows = sortProducts(rows); -// const result = [columns, ...sortedRows]; + const sortedRows = sortProducts(rows, "ascending"); + const result = [columns, ...sortedRows]; -// expect(result).toEqual([ -// ["product_code", "quantity", "pick_location"], -// ["C", "10", "A 1"], -// ["G", "1", "A 7"], -// ["A", "10", "Z 1"], -// ["B", "5", "Z 10"] -// ]); -// }); -// it("should sort an array of products by bay and shelf height in ascending order WHEN bays are the same FROM lowest to highest shelf", () => { -// const data: ProductTuple[] = [ -// ["product_code", "quantity", "pick_location"], -// ["E", "1", "AB 1"], -// ["F", "1", "AB 10"], -// ["H", "1", "AB 9"], -// ["H", "1", "AB 7"] -// ]; -// const [columns, ...rows] = data; + expect(result).toEqual([ + ["product_code", "quantity", "pick_location"], + ["C", "10", "A 1"], + ["G", "1", "A 7"], + ["A", "10", "Z 1"], + ["B", "5", "Z 10"] + ]); + }); + it("should sort an array of products by bay and shelf height in ascending order WHEN bays are the same FROM lowest to highest shelf", () => { + const data: ProductTuple[] = [ + ["product_code", "quantity", "pick_location"], + ["E", "1", "AB 1"], + ["F", "1", "AB 10"], + ["H", "1", "AB 9"], + ["H", "1", "AB 7"] + ]; + const [columns, ...rows] = data; -// const sortedRows = sortProducts(rows); -// const result = [columns, ...sortedRows]; + const sortedRows = sortProducts(rows, "ascending"); + const result = [columns, ...sortedRows]; -// expect(result).toEqual([ -// ["product_code", "quantity", "pick_location"], -// ["E", "1", "AB 1"], -// ["H", "1", "AB 7"], -// ["H", "1", "AB 9"], -// ["F", "1", "AB 10"] -// ]); -// }); + expect(result).toEqual([ + ["product_code", "quantity", "pick_location"], + ["E", "1", "AB 1"], + ["H", "1", "AB 7"], + ["H", "1", "AB 9"], + ["F", "1", "AB 10"] + ]); + }); -// it("should sort by shelf height if the bays are not the same", () => { -// const data: ProductTuple[] = [ -// ["product_code", "quantity", "pick_location"], -// ["B1237", "2", "A 10"], -// ["B1237", "2", "Z 10"], -// ["B1234", "2", "Z 3"], -// ["B1234", "2", "A 3"], -// ["B1235", "3", "Z 2"], -// ["B1236", "4", "Z 1"], -// ["B1235", "3", "A 2"], -// ["B1236", "4", "A 1"] -// ]; + it("should sort by shelf height if the bays are not the same", () => { + const data: ProductTuple[] = [ + ["product_code", "quantity", "pick_location"], + ["B1237", "2", "A 10"], + ["B1237", "2", "Z 10"], + ["B1234", "2", "Z 3"], + ["B1234", "2", "A 3"], + ["B1235", "3", "Z 2"], + ["B1236", "4", "Z 1"], + ["B1235", "3", "A 2"], + ["B1236", "4", "A 1"] + ]; -// const [columns, ...rows] = data; + const [columns, ...rows] = data; -// const sortedRows = sortProducts(rows); -// const result = [columns, ...sortedRows]; -// expect(result).toEqual([ -// ["product_code", "quantity", "pick_location"], -// ["B1236", "4", "A 1"], -// ["B1235", "3", "A 2"], -// ["B1234", "2", "A 3"], -// ["B1237", "2", "A 10"], -// ["B1236", "4", "Z 1"], -// ["B1235", "3", "Z 2"], -// ["B1234", "2", "Z 3"], -// ["B1237", "2", "Z 10"] -// ]); -// }); -// }); + const sortedRows = sortProducts(rows, "ascending"); + const result = [columns, ...sortedRows]; + expect(result).toEqual([ + ["product_code", "quantity", "pick_location"], + ["B1236", "4", "A 1"], + ["B1235", "3", "A 2"], + ["B1234", "2", "A 3"], + ["B1237", "2", "A 10"], + ["B1236", "4", "Z 1"], + ["B1235", "3", "Z 2"], + ["B1234", "2", "Z 3"], + ["B1237", "2", "Z 10"] + ]); + }); +}); describe("sortProducts", () => { - // TODO a to az const data: ProductTuple[] = [ ["product_code", "quantity", "pick_location"], ["1", "1", "AB 1"], @@ -149,17 +127,6 @@ describe("sortProducts", () => { ["3", "1", "AB 9"], ["4", "1", "AB 7"] ]; - // it("should throw an error if the pick location is invalid", () => { - // // - // // const [columns, ...rows] = data; - // // const result = newSortProducts(rows, "ascending"); - // // // console.log(''); - // // console.log("result", result); - // }); - - it("should correctly split a pick location into bay and shelf height", () => { - // - }); it("should sort products with the same bay by shelf height", () => { const [, ...rows] = data; @@ -205,8 +172,6 @@ describe("sortProducts", () => { it("should sort products that do not have the same bay by bay and then by shelf height", () => { const data: ProductTuple[] = [ ["product_code", "quantity", "pick_location"], - // ["1", "1", "A 1"], - // ["2", "1", "Z 1"], ["3", "1", "AB 10"], ["4", "1", "AB 9"], ["5", "1", "AB 7"], @@ -248,8 +213,12 @@ describe("sortProducts", () => { }); describe("compareStrings", () => { - // it("should return undefined if nothing matches", () => { - // // TODO empty case + it("should throw an error if the string is more than two characters", () => { + expect(() => compareStrings("ABC", "ABC")).toThrowError(); + expect(() => compareStrings("ABC", "AB")).toThrowError(); + expect(() => compareStrings("AB", "ABC")).toThrowError(); + expect(() => compareStrings("AB", "AB")).not.toThrowError(); + }); // }); describe("single char", () => { // Case 1: A, A - single chars, both match @@ -344,8 +313,4 @@ describe("compareStrings", () => { expect(result).toEqual(Compare.LESS_THAN); }); }); - - // describe("numeric shelf height", () => { - // // - // }); }); diff --git a/src/helpers/sort.ts b/src/helpers/sort.ts index 5594fdd..fec7c4d 100644 --- a/src/helpers/sort.ts +++ b/src/helpers/sort.ts @@ -80,6 +80,10 @@ export const compareStrings = (a: string, b: string) => { // Case 7: AA, Z - multiple chars, and single char // Case 8: Z, AA - single char, and multiple chars + if (a.length > 2 || b.length > 2) { + throw new Error("Invalid string length; string must be 2 characters or less."); + } + if (a.length === 1 && b.length === 1) { // Case 1: A, A - single chars, both match if (a === b) { @@ -122,8 +126,9 @@ export const compareStrings = (a: string, b: string) => { return Compare.LESS_THAN; } - // TODO default case and return value - return undefined; + // default case and return value + // should never be hit + return Compare.EQUALS; }; export const sortProducts = (products: ProductTuple[], method: SortMethod) => { @@ -149,11 +154,13 @@ export const sortProducts = (products: ProductTuple[], method: SortMethod) => { const compare = compareStrings(currentBay, nextBay); // top of the sort order + // Case 1: skip all less than results if (compare === Compare.LESS_THAN) { continue; } // swap based on shelf if both match + // Case 2: swap based on shelf if both match if (compare === Compare.EQUALS) { if (Number(currentShelf) > Number(nextShelf)) { swap(result, i, i + 1); @@ -162,6 +169,7 @@ export const sortProducts = (products: ProductTuple[], method: SortMethod) => { // swap based on bay if (compare === Compare.BIGGER_THAN) { + // TODO it was saying this wasn't tested before. swap(result, i, i + 1); } } From 9c70f4ae2da7809e9d4ff124b75b782374fff1a6 Mon Sep 17 00:00:00 2001 From: James Donnelly <4444684+JDIZM@users.noreply.github.com> Date: Tue, 20 Jun 2023 16:48:45 +0100 Subject: [PATCH 08/11] feat: fix test sort data and return default value --- src/helpers/sort.test.ts | 32 ++++++++++++++++---------------- src/helpers/sort.ts | 11 +++-------- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/helpers/sort.test.ts b/src/helpers/sort.test.ts index dad45d8..f3cbe41 100644 --- a/src/helpers/sort.test.ts +++ b/src/helpers/sort.test.ts @@ -72,7 +72,7 @@ describe("sortProducts", () => { ["E", "1", "AB 1"], ["F", "1", "AB 10"], ["H", "1", "AB 9"], - ["H", "1", "AB 7"] + ["J", "1", "AB 7"] ]; const [columns, ...rows] = data; @@ -82,7 +82,7 @@ describe("sortProducts", () => { expect(result).toEqual([ ["product_code", "quantity", "pick_location"], ["E", "1", "AB 1"], - ["H", "1", "AB 7"], + ["J", "1", "AB 7"], ["H", "1", "AB 9"], ["F", "1", "AB 10"] ]); @@ -92,13 +92,14 @@ describe("sortProducts", () => { const data: ProductTuple[] = [ ["product_code", "quantity", "pick_location"], ["B1237", "2", "A 10"], - ["B1237", "2", "Z 10"], + ["B1237", "2", "A 10"], + ["B12311", "2", "Z 10"], ["B1234", "2", "Z 3"], - ["B1234", "2", "A 3"], - ["B1235", "3", "Z 2"], - ["B1236", "4", "Z 1"], - ["B1235", "3", "A 2"], - ["B1236", "4", "A 1"] + ["B1235", "2", "A 3"], + ["B1236", "3", "Z 2"], + ["B1238", "4", "Z 1"], + ["B1239", "3", "A 2"], + ["B12310", "4", "A 1"] ]; const [columns, ...rows] = data; @@ -107,14 +108,14 @@ describe("sortProducts", () => { const result = [columns, ...sortedRows]; expect(result).toEqual([ ["product_code", "quantity", "pick_location"], - ["B1236", "4", "A 1"], - ["B1235", "3", "A 2"], - ["B1234", "2", "A 3"], - ["B1237", "2", "A 10"], - ["B1236", "4", "Z 1"], - ["B1235", "3", "Z 2"], + ["B12310", "4", "A 1"], + ["B1239", "3", "A 2"], + ["B1235", "2", "A 3"], + ["B1237", "4", "A 10"], + ["B1238", "4", "Z 1"], + ["B1236", "3", "Z 2"], ["B1234", "2", "Z 3"], - ["B1237", "2", "Z 10"] + ["B12311", "2", "Z 10"] ]); }); }); @@ -219,7 +220,6 @@ describe("compareStrings", () => { expect(() => compareStrings("AB", "ABC")).toThrowError(); expect(() => compareStrings("AB", "AB")).not.toThrowError(); }); - // }); describe("single char", () => { // Case 1: A, A - single chars, both match it("should return EQUALS if single chars, both match", () => { diff --git a/src/helpers/sort.ts b/src/helpers/sort.ts index fec7c4d..5a71ac1 100644 --- a/src/helpers/sort.ts +++ b/src/helpers/sort.ts @@ -122,13 +122,9 @@ export const compareStrings = (a: string, b: string) => { } // Case 8: Z, AA - single char, and multiple chars - if (a.length === 1 && b.length > 1) { - return Compare.LESS_THAN; - } - - // default case and return value - // should never be hit - return Compare.EQUALS; + // if (a.length === 1 && b.length > 1) { + return Compare.LESS_THAN; + // } }; export const sortProducts = (products: ProductTuple[], method: SortMethod) => { @@ -169,7 +165,6 @@ export const sortProducts = (products: ProductTuple[], method: SortMethod) => { // swap based on bay if (compare === Compare.BIGGER_THAN) { - // TODO it was saying this wasn't tested before. swap(result, i, i + 1); } } From c284f901fb9c4c686db1c39e310e925ff54d7d73 Mon Sep 17 00:00:00 2001 From: James Donnelly <4444684+JDIZM@users.noreply.github.com> Date: Tue, 20 Jun 2023 16:49:05 +0100 Subject: [PATCH 09/11] feat: implement new sort function --- src/index.ts | 4 ++-- src/output.csv | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/index.ts b/src/index.ts index 4b5e30d..0d943bc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -39,9 +39,9 @@ async function run(args: string[], options: CliOptions = {}) { checkColumns(columns); logger.info(`processing ${rows.length} rows`); - sortProducts(rows); + const sortedRows = sortProducts(rows, "ascending"); - const sortedProducts = [columns, ...rows]; + const sortedProducts = [columns, ...sortedRows]; logger.success(`sorted ${sortedProducts.length - 1} products`); createCsvFile(options.output, sortedProducts); diff --git a/src/output.csv b/src/output.csv index 600164e..c6c7373 100644 --- a/src/output.csv +++ b/src/output.csv @@ -1,9 +1,12 @@ product_code,quantity,pick_location 25214,10,A 1 30124,5,A 1 +25636,1,C 8 +15178,9,D 4 +12345,15,L 3 +23689,10,X 10 12456,10,AB 9 -15248,10,AB 10 -15248,5,AB 10 +15248,15,AB 10 52568,7,AB 10 33331,6,AC 4 36389,4,AC 5 @@ -13,8 +16,4 @@ product_code,quantity,pick_location 12879,12,AL 7 14789,3,AM 9 11224,8,AZ 4 -88958,4,AZ 10 -25636,1,C 8 -15178,9,D 4 -12345,15,L 3 -23689,10,X 10 \ No newline at end of file +88958,4,AZ 10 \ No newline at end of file From 393fa8499a703a5b38fbbc29b6b97960273a015e Mon Sep 17 00:00:00 2001 From: James Donnelly <4444684+JDIZM@users.noreply.github.com> Date: Tue, 20 Jun 2023 16:49:21 +0100 Subject: [PATCH 10/11] chore: v0.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3889322..c16f1a4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "csv-picker", - "version": "1.0.0", + "version": "0.2.0", "description": "", "main": "dist/src/index.js", "module": "dist/src/index.esm.js", From 5a18bd179ec6ac947a53be5236ad7c65bf5312b8 Mon Sep 17 00:00:00 2001 From: James Donnelly <4444684+JDIZM@users.noreply.github.com> Date: Tue, 20 Jun 2023 17:07:54 +0100 Subject: [PATCH 11/11] chore: update comment --- src/helpers/sort.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/helpers/sort.ts b/src/helpers/sort.ts index 5a71ac1..2b6def0 100644 --- a/src/helpers/sort.ts +++ b/src/helpers/sort.ts @@ -77,6 +77,7 @@ export const compareStrings = (a: string, b: string) => { // Case 5: ZA, AA - multiple chars, only second letters match // Case 6: ZA, AZ - multiple chars, no match + // Both // Case 7: AA, Z - multiple chars, and single char // Case 8: Z, AA - single char, and multiple chars @@ -155,7 +156,6 @@ export const sortProducts = (products: ProductTuple[], method: SortMethod) => { continue; } - // swap based on shelf if both match // Case 2: swap based on shelf if both match if (compare === Compare.EQUALS) { if (Number(currentShelf) > Number(nextShelf)) { @@ -163,7 +163,7 @@ export const sortProducts = (products: ProductTuple[], method: SortMethod) => { } } - // swap based on bay + // Case 3: swap based on bay if (compare === Compare.BIGGER_THAN) { swap(result, i, i + 1); }