Skip to content

Instantly share code, notes, and snippets.

@DmitryOlkhovoi
Created March 1, 2018 21:11
Show Gist options
  • Save DmitryOlkhovoi/ed30e081d4bcd8bc7f4aaabd20fce715 to your computer and use it in GitHub Desktop.
Save DmitryOlkhovoi/ed30e081d4bcd8bc7f4aaabd20fce715 to your computer and use it in GitHub Desktop.
index03.js
const products = [
{id: 1, price: 10}, {id: 2, price: 11}, {id: 3, price: 1},
{id: 4, price: 3}, {id: 5, price: 1}, {id: 6, price: 8},
{id: 7, price: 3}, {id: 8, price: 0}, {id: 9, price: 4},
{id: 10, price: 5}, {id: 11, price: 9}, {id: 12, price: 13},
];
// Don't like it, but don't like dublications as well :)
// We are not making a real world here, so, let's just do it a little bit clearer
const nullReturn = {
highest: null,
lowest: null,
}
const getFirstItems = (products, size) => {
return products.slice(0, size)
}
const getLastItems = (products, size) => {
const toSplice = (size * 2 > products.length) ?
products.length - size : size
if (toSplice <= 0) {
return null
}
return products.slice(-(toSplice))
}
const getHighestAndLowestItems = (products, size) => {
if (size > products.length || size === 0) {
return nullReturn
}
return {
highest: getFirstItems(products, size),
lowest: getLastItems(products, size)
}
}
const sortItems = (products) => {
return products.sort((a, b) => {
if (a.price < b.price) {
return 1
}
if (b.price < a.price) {
return -1
}
return 0
})
}
/*
Here we should assume that we consider two arrays with products equal if:
- They contain the same amount of items
- Links to the objecs(items) are the same
We don't consider modifications such:
- Diffrent sorting
- Deep mutations (products[0].price = 100)
*/
const equal = (a, b) => {
if (a == null || b == null) {
return false
}
const lenA = a.length
const lenB = b.length
if (lenA !== lenB) {
return false
}
for (let i = 0; i < lenA; i += 1) {
if (a[i] !== b[i]) {
return false
}
}
return true
}
// Ok, from task description it's not obvious could I do like that or no.
// Let's be real and write fn as it perfectly should looks like
function makeSortProducts() {
let lastCallItems = null
return (products, options = { size: 5 }) => {
const size = options.size >= 0 ? options.size : 5
const sortedProducts = sortItems(products)
if (lastCallItems && equal(sortedProducts, lastCallItems)) {
return nullReturn
} else {
lastCallItems = Array.from(sortedProducts)
}
return getHighestAndLowestItems(sortedProducts, size)
}
}
const sortProducts = makeSortProducts()
// Sorry guys, don't have much time left to write real world Unit tests :(
// toEql (jest)
/// beforeEach creates sortProducts (so we don't have lastCallItems)
expect(sortProducts(products)).toEql(expectedResult) // {highest: Array(5), lowest: Array(5)}
expect(sortProducts(products, { size: 0 })).toEql(expectedResult) // {highest: null, lowest: null}
expect(sortProducts(products, { size: -10 })).toEql(expectedResult) // {highest: Array(5), lowest: Array(5)}
expect(sortProducts(products, { size: 10 })).toEql(expectedResult) // {highest: Array(10), lowest: Array(2)}
expect(sortProducts(products, { size: 12 })).toEql(expectedResult) // {highest: Array(12), lowest: null}
expect(sortProducts(products, { size: 13 })).toEql(expectedResult) // {highest: null, lowest: null}
///
expect(sortProducts(products)).toEql(expectedResult) // {highest: Array(5), lowest: Array(5)}
expect(sortProducts(products)).toEql(expectedResult) // {highest: null, lowest: null}
products.push({id: 10, price: 15})
expect(sortProducts(products)).toEql(expectedResult) // {highest: Array(5), lowest: Array(5)}
expect(sortProducts(products)).toEql(expectedResult) // {highest: null, lowest: null}
products.length = 5
expect(sortProducts(products)).toEql(expectedResult) // {highest: Array(5), lowest: null}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment