Skip to content

Commit cd73aaf

Browse files
authored
Merge pull request #1 from JDIZM/update-sort-algo
Update sort algo
2 parents b252d32 + 5a18bd1 commit cd73aaf

File tree

5 files changed

+413
-67
lines changed

5 files changed

+413
-67
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "csv-picker",
3-
"version": "1.0.0",
3+
"version": "0.2.0",
44
"description": "",
55
"main": "dist/src/index.js",
66
"module": "dist/src/index.esm.js",

src/helpers/sort.test.ts

Lines changed: 246 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, expect, it, vi } from "vitest";
2-
import { swap, defaultCompare, sortProducts, ProductTuple } from "./sort";
2+
import { swap, ProductTuple, sortProducts, compareStrings, Compare } from "./sort";
33

44
describe("swap", () => {
55
it("should swap two items in an array", () => {
@@ -9,61 +9,43 @@ describe("swap", () => {
99
});
1010
});
1111

12-
describe("defaultCompare", () => {
13-
it("should return -1 if a < b", () => {
14-
const result = defaultCompare(1, 2);
15-
expect(result).toBe(-1);
16-
});
17-
it("should return 1 if a > b", () => {
18-
const result = defaultCompare(2, 1);
19-
expect(result).toBe(1);
20-
});
21-
it("should return 0 if a === b", () => {
22-
const result = defaultCompare(1, 1);
23-
expect(result).toBe(0);
24-
});
25-
});
26-
2712
describe("array sort", () => {
28-
it("should sort an array of numbers", () => {
29-
const array = [4, 2, 3, 1, 5];
30-
const result = array.sort((a, b) => defaultCompare(a, b));
31-
expect(result).toEqual([1, 2, 3, 4, 5]);
32-
});
33-
3413
it("should sort an array of strings", () => {
3514
const array = ["a", "z", "ag", "ac", "ab", "ae", "ba"];
36-
const result = array.sort((a, b) => defaultCompare(a, b));
37-
expect(result).toEqual(["a", "ab", "ac", "ae", "ag", "ba", "z"]);
15+
const result = array.sort((a, b) => compareStrings(a, b));
16+
expect(result).toEqual(["a", "z", "ab", "ac", "ae", "ag", "ba"]);
3817
});
18+
3919
it("should sort an array of strings that are numbers", () => {
4020
const array = ["5", "4", "3", "2", "1"];
41-
const result = array.sort((a, b) => defaultCompare(a, b));
21+
const result = array.sort((a, b) => compareStrings(a, b));
4222
expect(result).toEqual(["1", "2", "3", "4", "5"]);
4323
});
4424
});
4525

4626
describe("sortProducts", () => {
47-
it("should sort an array of products by pick location", () => {
27+
it("should sort an array of products by pick location in ascending order from A 1 to A 10", () => {
4828
const data: ProductTuple[] = [
4929
["product_code", "quantity", "pick_location"],
50-
["B1234", "2", "A3"],
51-
["B1235", "3", "A2"],
52-
["B1236", "4", "A1"]
30+
["B1237", "2", "A 10"],
31+
["B1234", "2", "A 3"],
32+
["B1235", "3", "A 2"],
33+
["B1236", "4", "A 1"]
5334
];
5435
const [columns, ...rows] = data;
5536

56-
const sortedRows = sortProducts(rows);
37+
const sortedRows = sortProducts(rows, "ascending");
5738
const result = [columns, ...sortedRows];
5839

5940
expect(result).toEqual([
6041
["product_code", "quantity", "pick_location"],
61-
["B1236", "4", "A1"],
62-
["B1235", "3", "A2"],
63-
["B1234", "2", "A3"]
42+
["B1236", "4", "A 1"],
43+
["B1235", "3", "A 2"],
44+
["B1234", "2", "A 3"],
45+
["B1237", "2", "A 10"]
6446
]);
6547
});
66-
it("should sort an array of products by bay and shelf height in ascending order", () => {
48+
it("should sort an array of products by pick location (bay and shelf height) in ascending order", () => {
6749
const data: ProductTuple[] = [
6850
["product_code", "quantity", "pick_location"],
6951
["A", "10", "Z 1"],
@@ -73,7 +55,7 @@ describe("sortProducts", () => {
7355
];
7456
const [columns, ...rows] = data;
7557

76-
const sortedRows = sortProducts(rows);
58+
const sortedRows = sortProducts(rows, "ascending");
7759
const result = [columns, ...sortedRows];
7860

7961
expect(result).toEqual([
@@ -90,19 +72,245 @@ describe("sortProducts", () => {
9072
["E", "1", "AB 1"],
9173
["F", "1", "AB 10"],
9274
["H", "1", "AB 9"],
93-
["H", "1", "AB 7"]
75+
["J", "1", "AB 7"]
9476
];
9577
const [columns, ...rows] = data;
9678

97-
const sortedRows = sortProducts(rows);
79+
const sortedRows = sortProducts(rows, "ascending");
9880
const result = [columns, ...sortedRows];
9981

10082
expect(result).toEqual([
10183
["product_code", "quantity", "pick_location"],
10284
["E", "1", "AB 1"],
103-
["H", "1", "AB 7"],
85+
["J", "1", "AB 7"],
10486
["H", "1", "AB 9"],
10587
["F", "1", "AB 10"]
10688
]);
10789
});
90+
91+
it("should sort by shelf height if the bays are not the same", () => {
92+
const data: ProductTuple[] = [
93+
["product_code", "quantity", "pick_location"],
94+
["B1237", "2", "A 10"],
95+
["B1237", "2", "A 10"],
96+
["B12311", "2", "Z 10"],
97+
["B1234", "2", "Z 3"],
98+
["B1235", "2", "A 3"],
99+
["B1236", "3", "Z 2"],
100+
["B1238", "4", "Z 1"],
101+
["B1239", "3", "A 2"],
102+
["B12310", "4", "A 1"]
103+
];
104+
105+
const [columns, ...rows] = data;
106+
107+
const sortedRows = sortProducts(rows, "ascending");
108+
const result = [columns, ...sortedRows];
109+
expect(result).toEqual([
110+
["product_code", "quantity", "pick_location"],
111+
["B12310", "4", "A 1"],
112+
["B1239", "3", "A 2"],
113+
["B1235", "2", "A 3"],
114+
["B1237", "4", "A 10"],
115+
["B1238", "4", "Z 1"],
116+
["B1236", "3", "Z 2"],
117+
["B1234", "2", "Z 3"],
118+
["B12311", "2", "Z 10"]
119+
]);
120+
});
121+
});
122+
123+
describe("sortProducts", () => {
124+
const data: ProductTuple[] = [
125+
["product_code", "quantity", "pick_location"],
126+
["1", "1", "AB 1"],
127+
["2", "1", "AB 10"],
128+
["3", "1", "AB 9"],
129+
["4", "1", "AB 7"]
130+
];
131+
132+
it("should sort products with the same bay by shelf height", () => {
133+
const [, ...rows] = data;
134+
const result = sortProducts(rows, "ascending");
135+
expect(result).toEqual([
136+
["1", "1", "AB 1"],
137+
["4", "1", "AB 7"],
138+
["3", "1", "AB 9"],
139+
["2", "1", "AB 10"]
140+
]);
141+
});
142+
143+
it('should reverse the results if the method is "descending"', () => {
144+
const [, ...rows] = data;
145+
const result = sortProducts(rows, "descending");
146+
expect(result).toEqual([
147+
["2", "1", "AB 10"],
148+
["3", "1", "AB 9"],
149+
["4", "1", "AB 7"],
150+
["1", "1", "AB 1"]
151+
]);
152+
});
153+
154+
it("should deduplicate products by id and add their qty", () => {
155+
const data: ProductTuple[] = [
156+
["product_code", "quantity", "pick_location"],
157+
["1", "1", "AB 1"],
158+
["1", "1", "AB 1"],
159+
["2", "1", "AB 10"],
160+
["3", "1", "AB 9"],
161+
["4", "1", "AB 7"]
162+
];
163+
const [, ...rows] = data;
164+
const result = sortProducts(rows, "descending");
165+
expect(result).toEqual([
166+
["2", "1", "AB 10"],
167+
["3", "1", "AB 9"],
168+
["4", "1", "AB 7"],
169+
["1", "2", "AB 1"]
170+
]);
171+
});
172+
173+
it("should sort products that do not have the same bay by bay and then by shelf height", () => {
174+
const data: ProductTuple[] = [
175+
["product_code", "quantity", "pick_location"],
176+
["3", "1", "AB 10"],
177+
["4", "1", "AB 9"],
178+
["5", "1", "AB 7"],
179+
["6", "1", "AZ 1"],
180+
["7", "1", "AZ 10"],
181+
["8", "1", "AZ 9"],
182+
["9", "1", "AZ 7"]
183+
];
184+
const [, ...rows] = data;
185+
const result = sortProducts(rows, "ascending");
186+
expect(result).toEqual([
187+
["5", "1", "AB 7"],
188+
["4", "1", "AB 9"],
189+
["3", "1", "AB 10"],
190+
["6", "1", "AZ 1"],
191+
["9", "1", "AZ 7"],
192+
["8", "1", "AZ 9"],
193+
["7", "1", "AZ 10"]
194+
]);
195+
});
196+
197+
it("should sort an array of products by pick location in ascending order from A 1 to AZ 10", () => {
198+
const data: ProductTuple[] = [
199+
["product_code", "quantity", "pick_location"],
200+
["1", "1", "A 1"],
201+
["2", "1", "Z 1"],
202+
["3", "1", "AB 10"],
203+
["9", "1", "AZ 7"]
204+
];
205+
const [, ...rows] = data;
206+
const result = sortProducts(rows, "ascending");
207+
expect(result).toEqual([
208+
["1", "1", "A 1"],
209+
["2", "1", "Z 1"],
210+
["3", "1", "AB 10"],
211+
["9", "1", "AZ 7"]
212+
]);
213+
});
214+
});
215+
216+
describe("compareStrings", () => {
217+
it("should throw an error if the string is more than two characters", () => {
218+
expect(() => compareStrings("ABC", "ABC")).toThrowError();
219+
expect(() => compareStrings("ABC", "AB")).toThrowError();
220+
expect(() => compareStrings("AB", "ABC")).toThrowError();
221+
expect(() => compareStrings("AB", "AB")).not.toThrowError();
222+
});
223+
describe("single char", () => {
224+
// Case 1: A, A - single chars, both match
225+
it("should return EQUALS if single chars, both match", () => {
226+
const data = ["A", "A"];
227+
const result = compareStrings(data[0], data[1]);
228+
expect(result).toEqual(Compare.EQUALS);
229+
});
230+
231+
// Case 2: A, Z || Z, A - single chars, no match
232+
it("should return BIGGER THAN if single chars, no match", () => {
233+
const data = ["Z", "A"];
234+
const result = compareStrings(data[0], data[1]);
235+
expect(result).toEqual(Compare.BIGGER_THAN);
236+
});
237+
238+
it("should return LESS THAN if single chars, no match", () => {
239+
const data = ["A", "Z"];
240+
const result = compareStrings(data[0], data[1]);
241+
expect(result).toEqual(Compare.LESS_THAN);
242+
});
243+
});
244+
245+
describe("multiple chars", () => {
246+
// Case 3: AA, AA - multiple chars, both match
247+
it("should return EQUALS if the first and second letters are the same", () => {
248+
const data = ["AA", "AA"];
249+
const result = compareStrings(data[0], data[1]);
250+
expect(result).toEqual(Compare.EQUALS);
251+
});
252+
253+
// Case 4: AA, AZ - multiple chars, only first letters match
254+
it("should return LESS THAN if the first letters match but the second char is lower", () => {
255+
const data = ["AA", "AB"];
256+
const result = compareStrings(data[0], data[1]);
257+
expect(result).toEqual(Compare.LESS_THAN);
258+
});
259+
260+
it("should return BIGGER THAN if the first letters match but the second char is higher", () => {
261+
const data = ["AB", "AA"];
262+
const result = compareStrings(data[0], data[1]);
263+
expect(result).toEqual(Compare.BIGGER_THAN);
264+
});
265+
266+
// Case 5: ZA, AA - multiple chars, only second letters match
267+
it("should return LESS THAN if the first letters dont match and only second letters match", () => {
268+
const data = ["AA", "BA"];
269+
const result = compareStrings(data[0], data[1]);
270+
expect(result).toEqual(Compare.LESS_THAN);
271+
});
272+
273+
it("should return BIGGER THAN if the first letters dont match and only second letters match", () => {
274+
const data = ["BA", "AA"];
275+
const result = compareStrings(data[0], data[1]);
276+
expect(result).toEqual(Compare.BIGGER_THAN);
277+
});
278+
279+
// Case 6: ZA, AZ - multiple chars, no match
280+
it("should return BIGGER THAN if no chars match and the first char is lower", () => {
281+
const data = [
282+
["ZA", "AZ"],
283+
["XY", "AK"]
284+
];
285+
data.forEach(([a, b]) => {
286+
const result = compareStrings(a, b);
287+
expect(result).toEqual(Compare.BIGGER_THAN);
288+
});
289+
});
290+
291+
it("should return LESS THAN if no chars match and the first char is higher", () => {
292+
const data = [
293+
["AZ", "ZA"],
294+
["KA", "XY"]
295+
];
296+
data.forEach(([a, b]) => {
297+
const result = compareStrings(a, b);
298+
expect(result).toEqual(Compare.LESS_THAN);
299+
});
300+
});
301+
302+
// Case 7: AA, Z - multiple chars, and single char
303+
it("should return BIGGER THAN if the first string is multiple chars and the second is a single char", () => {
304+
const data = ["AA", "Z"];
305+
const result = compareStrings(data[0], data[1]);
306+
expect(result).toEqual(Compare.BIGGER_THAN);
307+
});
308+
309+
// Case 8: Z, AA - single char, and multiple chars
310+
it("should return LESS THAN if the first string is a single char and second is multiple", () => {
311+
const data = ["Z", "AA"];
312+
const result = compareStrings(data[0], data[1]);
313+
expect(result).toEqual(Compare.LESS_THAN);
314+
});
315+
});
108316
});

0 commit comments

Comments
 (0)