Created
March 14, 2023 06:45
-
-
Save AnandPilania/e0f8ddbabec3b497eef0f8a9d22ad318 to your computer and use it in GitHub Desktop.
JS Collection : A port of Laravel Collection
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
let Collection = function (data) { | |
this.data = data || []; | |
}; | |
Collection.make = function (data) { | |
return new Collection(data); | |
}; | |
Collection.prototype = { | |
all: function () { | |
return this.data; | |
}, | |
avg: function (key = null) { | |
const count = this.count(); | |
if (count === 0) { | |
return 0; | |
} else { | |
return this.sum(key) / count; | |
} | |
}, | |
chunk: function (size) { | |
const chunks = []; | |
let index = 0; | |
while (index < this.data.length) { | |
chunks.push(this.data.slice(index, size + index)); | |
index += size; | |
} | |
return new Collection(chunks); | |
}, | |
collapse: function () { | |
const flattened = this.data.reduce((accumulator, currentValue) => { | |
if (Array.isArray(currentValue)) { | |
return accumulator.concat(currentValue); | |
} else { | |
accumulator.push(currentValue); | |
return accumulator; | |
} | |
}, []); | |
return new Collection(flattened); | |
}, | |
combine: function (values) { | |
const keys = this.data; | |
const combined = {}; | |
keys.forEach((key, index) => { | |
combined[key] = values[index]; | |
}); | |
return new Collection(combined); | |
}, | |
contains: function (value) { | |
if (Array.isArray(this.data)) { | |
return this.data.includes(value); | |
} else { | |
return Object.values(this.data).includes(value); | |
} | |
}, | |
count: function () { | |
return this.data.length; | |
}, | |
diff: function (values) { | |
const diff = this.data.filter((item) => !values.includes(item)); | |
return new Collection(diff); | |
}, | |
each: function (callback) { | |
this.data.forEach(callback); | |
return this; | |
}, | |
filter: function (callback) { | |
const filtered = this.data.filter(callback); | |
return new Collection(filtered); | |
}, | |
first: function () { | |
return this.data[0]; | |
}, | |
flatten: function (depth = Infinity) { | |
const flattened = this.data.reduce((result, item) => { | |
if (Array.isArray(item) && depth > 0) { | |
const flattenedSubArray = new Collection(item).flatten(depth - 1).all(); | |
result.push(...flattenedSubArray); | |
} else { | |
result.push(item); | |
} | |
return result; | |
}, []); | |
return new Collection(flattened); | |
}, | |
flip: function () { | |
const flipped = {}; | |
Object.entries(this.data).forEach(([key, value]) => { | |
flipped[value] = key; | |
}); | |
return new Collection(flipped); | |
}, | |
forget: function (key) { | |
delete this.data[key]; | |
return this; | |
}, | |
get: function (key, defaultValue = null) { | |
return this.data[key] ?? defaultValue; | |
}, | |
groupBy: function (callback) { | |
const grouped = this.data.reduce((result, item) => { | |
const key = callback(item); | |
if (!result[key]) { | |
result[key] = new Collection(); | |
} | |
result[key].push(item); | |
return result; | |
}, {}); | |
return new Collection(grouped); | |
}, | |
has: function (key) { | |
return Object.keys(this.data).includes(key); | |
}, | |
implode: function (glue, key = null) { | |
if (key) { | |
return this.pluck(key).all().join(glue); | |
} else { | |
return this.data.join(glue); | |
} | |
}, | |
intersect: function (values) { | |
const intersection = this.data.filter((item) => values.includes(item)); | |
return new Collection(intersection); | |
}, | |
isEmpty: function () { | |
return this.count() === 0; | |
}, | |
isNotEmpty: function () { | |
return !this.isEmpty(); | |
}, | |
keyBy: function (key) { | |
const keyed = {}; | |
this.data.forEach((item) => { | |
const value = item[key]; | |
keyed[value] = item; | |
}); | |
return new Collection(keyed); | |
}, | |
keys: function () { | |
const keys = Object.keys(this.data); | |
return new Collection(keys); | |
}, | |
last: function () { | |
return this.data[this.count() - 1]; | |
}, | |
map: function (callback) { | |
const mapped = this.data.map(callback); | |
return new Collection(mapped); | |
}, | |
max: function (key = null) { | |
if (key === null) { | |
return Math.max(...this.data); | |
} else { | |
return this.pluck(key).max(); | |
} | |
}, | |
min: function (key = null) { | |
if (key === null) { | |
return Math.min(...this.data); | |
} else { | |
return this.pluck(key).min(); | |
} | |
}, | |
pluck: function (key) { | |
const plucked = this.data.map((item) => item[key]); | |
return new Collection(plucked); | |
}, | |
pop: function () { | |
this.data.pop(); | |
return this; | |
}, | |
push: function (item) { | |
this.data.push(item); | |
return this; | |
}, | |
reduce: function (callback, initial = null) { | |
return initial === null ? this.data.reduce(callback) : this.data.reduce(callback, initial); | |
}, | |
reject: function (callback) { | |
const rejected = this.data.filter((item) => !callback(item)); | |
return new Collection(rejected); | |
}, | |
reverse: function () { | |
const reversed = this.data.slice().reverse(); | |
return new Collection(reversed); | |
}, | |
shift: function () { | |
return this.data.shift(); | |
}, | |
sortBy: function (callback) { | |
const sorted = this.data.slice().sort((a, b) => { | |
const aKey = callback(a); | |
const bKey = callback(b); | |
if (aKey < bKey) return -1; | |
if (aKey > bKey) return 1; | |
return 0; | |
}); | |
return new Collection(sorted); | |
}, | |
splice: function (index, length = 0, replacement = []) { | |
const removed = this.data.splice(index, length, ...replacement); | |
return new Collection(removed); | |
}, | |
sum: function (key = null) { | |
if (key === null) { | |
return this.data.reduce((sum, item) => sum + item, 0); | |
} else { | |
return this.pluck(key).sum(); | |
} | |
}, | |
tap: function (callback) { | |
callback(this); | |
return this; | |
}, | |
toArray: function () { | |
return this.data.slice(); | |
}, | |
toJson: function () { | |
return JSON.stringify(this.data); | |
}, | |
toObject: function () { | |
const obj = {}; | |
for (let i = 0; i < this.data.length; i++) { | |
const item = this.data[i]; | |
if (typeof item === 'object' && item !== null) { | |
Object.assign(obj, item); | |
} | |
} | |
return obj; | |
}, | |
toString: function () { | |
return this.data.join(', '); | |
}, | |
unshift: function (item) { | |
this.data.unshift(item); | |
return this; | |
}, | |
when: function (value, callback) { | |
if (value) { | |
return callback(this); | |
} else { | |
return this; | |
} | |
}, | |
}; | |
Array.prototype.collect = function (callback) { | |
const mapped = (typeof callback === 'function' ? this.map(callback) : this); | |
return new Collection(mapped); | |
}; | |
Object.prototype.collect = function (callback) { | |
const mapped = (typeof callback === 'function' ? Object.keys(this).map((key) => callback(this[key], key)) : this); | |
return new Collection(typeof callback === 'object' || typeof callback === 'array' ? callback : mapped); | |
}; | |
let collect; | |
if (typeof jQuery !== 'undefined') { | |
(function ($) { | |
$.Collection = Collection; | |
collect = d => new $.Collection(d); | |
})(jQuery); | |
} else { | |
collect = d => new Collection(d); | |
} | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log(collect({a:'a'})); | |
console.log(collect([1,2,3,4,5,6])); | |
console.log([1,2,3,4,5,6].collect()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment