array_prototypes.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. [{anyField:1,weight:1},{anyField:2,weight:2}].getRandomWeighted()
  3. will return the first array entry with 1/3 chance and the second with 2/3 chance
  4. Any fields are allowed as long as a weight-field is present.
  5. Any array-size is allowed.
  6. */
  7. Array.prototype.avg ??= function(){
  8. return this.reduce( ( p, c ) => p + c, 0 ) / (this.length || 1);
  9. }
  10. Array.prototype.filterByObject ??= function(filter){
  11. let result = [];
  12. entryloop:for(const entry of this){
  13. filterloop:for(const [filterKey, filterValue] of Object.entries(filter)){
  14. const fieldValueOfEntry = entry[filterKey];
  15. if(typeof filterValue == "object"){
  16. if(Object.keys(filterValue).length == 0){
  17. if(typeof fieldValueOfEntry == "object")
  18. continue filterloop;
  19. continue entryloop;
  20. }
  21. if("max" in filterValue){
  22. if(typeof fieldValueOfEntry != "number" || fieldValueOfEntry > filterValue.max)
  23. continue entryloop;
  24. }
  25. if("min" in filterValue){
  26. if(typeof fieldValueOfEntry != "number" || fieldValueOfEntry < filterValue.min)
  27. continue entryloop;
  28. }
  29. }else{
  30. if(fieldValueOfEntry != filterValue)
  31. continue entryloop;
  32. }
  33. }
  34. result.push(entry);
  35. }
  36. return result;
  37. }
  38. Array.prototype.getRandomWeightedId = function(flags={}){
  39. if(flags.isKeyValuePair){
  40. const mapped = this.map(([key,entry]) => Object.assign({},entry,{id:key}));
  41. return mapped.getRandomWeighted();
  42. }
  43. let weightSum = this.reduce((accumulator, currentValue) => accumulator + currentValue.weight,0);
  44. let weightRandom = rand(1,weightSum);
  45. //for(let entry of this){
  46. for(const entryId in this){
  47. const entry = this[entryId];
  48. weightRandom -= entry.weight;
  49. if(weightRandom <= 0)
  50. return entryId;
  51. }
  52. }
  53. Array.prototype.pluckRandomWeighted = function(){
  54. if(this.length == 0)
  55. return null;
  56. const resultId = this.getRandomWeightedId();
  57. const result = this[resultId];
  58. this.splice(resultId,1);
  59. return result;
  60. }
  61. Array.prototype.groupBy = function(key){
  62. let result = {};
  63. for(const entry of this){
  64. result[entry[key]] ??= [];
  65. result[entry[key]].push(entry);
  66. }
  67. return result;
  68. }
  69. if(!Array.prototype.toReversed)
  70. Array.prototype.toReversed = function(){
  71. let copy = clone(this);
  72. return copy.reverse();
  73. }
  74. Array.prototype.keepSize ??= function(n) {
  75. if (this.length > n) {
  76. const elementsToRemove = this.length - n;
  77. this.splice(0, elementsToRemove);
  78. }
  79. };