agentscript
Version:
AgentScript Model in Model/View architecture
481 lines (459 loc) • 32.7 kB
HTML
<html lang="en" style="font-size:16px"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="../favicon.ico"><title>Source: AgentArray.js</title><!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]--><script src="scripts/third-party/hljs.js" defer="defer"></script><script src="scripts/third-party/hljs-line-num.js" defer="defer"></script><script src="scripts/third-party/popper.js" defer="defer"></script><script src="scripts/third-party/tippy.js" defer="defer"></script><script src="scripts/third-party/tocbot.min.js"></script><script>var baseURL="/",locationPathname="";baseURL=(locationPathname=document.location.pathname).substr(0,locationPathname.lastIndexOf("/")+1)</script><link rel="stylesheet" href="styles/clean-jsdoc-theme.min.css"><svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"><defs><symbol id="copy-icon" viewbox="0 0 488.3 488.3"><g><path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z"/><path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z"/></g></symbol><symbol id="search-icon" viewBox="0 0 512 512"><g><g><path d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474 c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323 c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848 S326.847,409.323,225.474,409.323z"/></g></g><g><g><path d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328 c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/></g></g></symbol><symbol id="font-size-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11.246 15H4.754l-2 5H.6L7 4h2l6.4 16h-2.154l-2-5zm-.8-2L8 6.885 5.554 13h4.892zM21 12.535V12h2v8h-2v-.535a4 4 0 1 1 0-6.93zM19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></symbol><symbol id="add-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></symbol><symbol id="minus-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 11h14v2H5z"/></symbol><symbol id="dark-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/></symbol><symbol id="light-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></symbol><symbol id="reset-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18.537 19.567A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 2.136-.67 4.116-1.81 5.74L17 12h3a8 8 0 1 0-2.46 5.772l.997 1.795z"/></symbol><symbol id="down-icon" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"></path></symbol><symbol id="codepen-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M16.5 13.202L13 15.535v3.596L19.197 15 16.5 13.202zM14.697 12L12 10.202 9.303 12 12 13.798 14.697 12zM20 10.869L18.303 12 20 13.131V10.87zM19.197 9L13 4.869v3.596l3.5 2.333L19.197 9zM7.5 10.798L11 8.465V4.869L4.803 9 7.5 10.798zM4.803 15L11 19.131v-3.596l-3.5-2.333L4.803 15zM4 13.131L5.697 12 4 10.869v2.262zM2 9a1 1 0 0 1 .445-.832l9-6a1 1 0 0 1 1.11 0l9 6A1 1 0 0 1 22 9v6a1 1 0 0 1-.445.832l-9 6a1 1 0 0 1-1.11 0l-9-6A1 1 0 0 1 2 15V9z"/></symbol><symbol id="close-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></symbol><symbol id="menu-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"/></symbol></defs></svg></head><body data-theme="dark"><div class="sidebar-container"><div class="sidebar" id="sidebar"><a href="/" class="sidebar-title sidebar-title-anchor">Home</a><div class="sidebar-items-container"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="AgentArray.html">AgentArray</a></div><div class="sidebar-section-children"><a href="AgentList.html">AgentList</a></div><div class="sidebar-section-children"><a href="AgentSet.html">AgentSet</a></div><div class="sidebar-section-children"><a href="Animator.html">Animator</a></div><div class="sidebar-section-children"><a href="DataSet.html">DataSet</a></div><div class="sidebar-section-children"><a href="GUI.html">GUI</a></div><div class="sidebar-section-children"><a href="GeoDataSet.html">GeoDataSet</a></div><div class="sidebar-section-children"><a href="Keyboard.html">Keyboard</a></div><div class="sidebar-section-children"><a href="Link.html">Link</a></div><div class="sidebar-section-children"><a href="Links.html">Links</a></div><div class="sidebar-section-children"><a href="Model.html">Model</a></div><div class="sidebar-section-children"><a href="Model3D.html">Model3D</a></div><div class="sidebar-section-children"><a href="Mouse.html">Mouse</a></div><div class="sidebar-section-children"><a href="Patch.html">Patch</a></div><div class="sidebar-section-children"><a href="Patches.html">Patches</a></div><div class="sidebar-section-children"><a href="RGBDataSet.html">RGBDataSet</a></div><div class="sidebar-section-children"><a href="ThreeDraw.html">ThreeDraw</a></div><div class="sidebar-section-children"><a href="Turtle.html">Turtle</a></div><div class="sidebar-section-children"><a href="Turtle3D.html">Turtle3D</a></div><div class="sidebar-section-children"><a href="Turtles.html">Turtles</a></div><div class="sidebar-section-children"><a href="TwoDraw.html">TwoDraw</a></div><div class="sidebar-section-children"><a href="World.html">World</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-src_geojson.html">src/geojson</a></div><div class="sidebar-section-children"><a href="module-src_gis.html">src/gis</a></div><div class="sidebar-section-children"><a href="module-src_utils.html">src/utils</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-tutorials"><div>Tutorials</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="tutorial-1 - AgentScript.html">1 - AgentScript</a></div><div class="sidebar-section-children"><a href="tutorial-2 - JavaScript.html">2 - JavaScript</a></div><div class="sidebar-section-children"><a href="tutorial-3 - Browser.html">3 - Browser</a></div><div class="sidebar-section-children"><a href="tutorial-4 - Model.html">4 - Model</a></div><div class="sidebar-section-children"><a href="tutorial-5 - View.html">5 - View</a></div><div class="sidebar-section-children"><a href="tutorial-6.1 - AnimatorController.html">6.1 - AnimatorController</a></div><div class="sidebar-section-children"><a href="tutorial-6.2 - KeyboardController.html">6.2 - KeyboardController</a></div><div class="sidebar-section-children"><a href="tutorial-6.3 - GuiController.html">6.3 - GuiController</a></div><div class="sidebar-section-children"><a href="tutorial-6.4 - MouseController.html">6.4 - MouseController</a></div><div class="sidebar-section-children"><a href="tutorial-7 - CodePenServer.html">7 - CodePenServer</a></div></div></div></div></div><div class="navbar-container" id="VuAckcnZhf"><nav class="navbar"><div class="navbar-left-items"><div class="navbar-item"><a id="github" href="https://github.com/backspaces/agentscript" target="">Github</a></div><div class="navbar-item"><a id="AgentScript" href="https://code.agentscript.org" target="">AgentScript.org</a></div><div class="navbar-item"><a id="npm" href="https://www.npmjs.com/package/agentscript" target="">npm</a></div><div class="navbar-item"><a id="unpkg" href="https://unpkg.com/browse/agentscript/" target="">unpkg</a></div></div><div class="navbar-right-items"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#light-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div><nav></nav></nav></div><div class="toc-container"><div class="toc-content"><span class="bold">On this page</span><div id="eed4d2a0bfd64539bb9df78095dec881"></div></div></div><div class="body-wrapper"><div class="main-content"><div class="main-wrapper"><section id="source-page" class="source-page"><header><h1 id="title" class="has-anchor">AgentArray.js</h1></header><article><pre class="prettyprint source lang-js"><code>import * as util from './utils.js'
/**
* Subclass of Array with convenience methods used by NetLogo.
* Typically the items in the array are Objects but can be any type.
*/
class AgentArray extends Array {
/**
* Magic to return AgentArrays rather than AgentList
* or other AgentArray subclasses when using AA methods
* [Symbol.species](https://goo.gl/Zsxwxd)
*
* @readonly
*/
static get [Symbol.species]() {
return AgentArray
}
/**
* Convert an existing Array to an AgentArray "in place".
* Use array.slice() if a new array is wanted
*
* @param {Array} array Array to convert to AgentArray
* @returns {AgentArray} array converted to AgentArray
*/
static fromArray(array) {
const aarray = Object.setPrototypeOf(array, AgentArray.prototype)
return aarray
}
/**
* Creates an instance of AgentArray. Simply pass-through to super()
* now, but may add initialization code later.
* @param {*} args Zero or more items in Array
* @example
* let aa = new AgentArray({x:0,y:0}, {x:0,y:1}, {x:1,y:0})
* //=> [{ x: 0, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 0 }]
*/
constructor(...args) {
super(...args)
// maybe do some initialization later
}
/**
* See {@link World} and [MyClass's foo property]{@link World#bboxTransform}.
* Convert this AgentArray to Array in-place
*
* @returns {Array} This AgentArray converted to Array
*/
toArray() {
Object.setPrototypeOf(this, Array.prototype)
return this
}
// NL: Return true if reporter true for all of this set's objects
// Use Array.every(). Also Array.some()
// all (reporter) { return this.every(reporter) }
// // Return !isEmpty()
// any () { return this.length !== 0 }
// NL: Return AgentArray with reporter(agent) true. Use Array.filter()
// with (reporter) { return this.filter(reporter) }
/**
* Return true if there are no items in this Array
*
* @returns {boolean}
* @example
* new AgentArray().isEmpty()
* //=> true
* @example
* aa.isEmpty()
* //=> false
*/
isEmpty() {
return this.length === 0
}
/**
* Return first item in this array. Returns undefined if empty.
*
* @returns {any}
* @example
* aa.first()
* //=> { x: 0, y: 0 }
*/
first() {
return this[0]
}
/**
* Return last item in this array. Returns undefined if empty.
*
* @returns {any}
* @example
* aa.last()
* //=> { x: 1, y: 0 }
*/
last() {
return this[this.length - 1]
}
/**
* Return at index. Returns undefined if empty.
* Wrap the index to be within the array.
*
* @returns {any}
* @example
* aa.atIndex(aa.length)
* //=> { x: 0, y: 0 }
*/
atIndex(i) {
if (this.length === 0) return undefined
const index = util.mod(i, this.length)
return this[index]
}
/**
* Return true if fcn(element) returns true for each element in this array.
* Same as Array.every, using NetLogo's name
*
* @param {Function} fcn fcn(element) return boolean
* @returns {boolean} true if fcn returns true for all elements
*/
all(fcn) {
return this.every(fcn)
}
/**
* Return array of property values from this array's objects.
* Array type is specified, defaults to AgentArray
*
* @param {String} key Property name
* @param {Array} [type=AgentArray] Type of array (Array, Uint8Array, ...)
* @returns {Array} Array of given type
* @example
* aa.props('x')
* //=> [0, 0, 1]
* @example
* aa.props('y')
* //=> [0, 1, 0]
*/
props(key, type = AgentArray) {
const result = new type(this.length)
for (let i = 0; i < this.length; i++) {
result[i] = this[i][key]
}
return result
}
// Creates an OofA for several sets of props.
// Obj is key, arrayType pairs: x: Float32Array
// Result is this.props(key, arrayType) for each key
/**
* Creates an Object of Arrays, one Array per each property in obj.
* Obj is key, arrayType pairs: x: Float32Array
* This is advanced, used for web workers, very large data sets, and remote communication
*
* @param {Object} obj Object of prop, array type pairs
* @returns {Object}
* @example
* aa.typedSample({x: Uint8Array, y: Uint8Array})
* //=> {x: new Uint8Array([0, 0, 1]), y: new Uint8Array([0, 1, 0])}
*/
typedSample(obj) {
// const length = this.length
const result = {}
// note: use util's forLoop, does not iterate over this agent array.
util.forLoop(obj, (val, key) => {
result[key] = this.props(key, val)
})
return result
}
// Return AgentArray of results of the function fcn
// Similar to "props" but can return computation over all keys
// Odd: as.props('type') twice as fast as as.results(p => p.type)?
// results(fcn) {
// const result = new AgentArray(this.length)
// for (let i = 0; i < this.length; i++) {
// result[i] = fcn(this[i])
// }
// return result
// }
/**
* Return new AgentArray of the unique values of this array
*
* @returns {AgentArray}
*/
uniq() {
// return AgentArray.fromArray(Array.from(new Set(this)))
return AgentArray.from(new Set(this))
}
/**
* Call fcn(agent, index, array) for each item in AgentArray.
* Index & array optional.
* Array assumed not mutable.
* Note: 5x+ faster than this.forEach(fcn)
*
* @param {Function} fcn fcn(agent, [index], [array])
* @returns {this} Return this for chaining.
*/
forLoop(fcn) {
for (let i = 0, len = this.length; i < len; i++) {
fcn(this[i], i, this)
}
return this
}
/**
* Call fcn(agent, [ i, AgentArray ]) for each agent in AgentArray.
* where i = agent's array index and AgentArray is this array
* Array can shrink. If it grows, will not visit beyond original length.
* If it either shrinks or grows, it will console.log a message
* "ask" is NetLogo term.
*
* @param {Function} fcn fcn(agent, [index], [array])
*/
ask(fcn) {
const length = this.length
// for (let i = 0; i < length || i < this.length; i++) {
for (let i = 0; i < Math.min(length, this.length); i++) {
fcn(this[i], i, this)
}
if (length != this.length) {
const name = this.name || this.constructor.name
const direction = this.length < length ? 'decreasing' : 'increasing'
util.warn(`AgentArray.ask array mutation: ${name}: ${direction}`)
}
// return this
}
/**
* Return all elements returning f(obj, [index, array]) true, as in ask()
* NetLogo term, simply calls this.filter(fcn)
*
* @param {Function} fcn fcn(agent, [index], [array])
* @returns {AgentArray}
* @description
* Use: turtles.with(t => t.foo > 20).ask(t => t.bar = true)
*/
with(fcn) {
return this.filter(fcn)
}
// Return all other than me.
other(t) {
return this.filter(o => o !== t)
}
// Return an AgentArray of values for each object in AgentArray
//
// If fcn is a string, it will return that property value.
// Otherwise it returns the value returned from fcn(obj)
getValues(fcn) {
const props = new AgentArray()
if (util.isString(fcn)) {
this.forLoop(obj => props.push(obj[fcn]))
} else {
this.forLoop(obj => props.push(fcn(obj)))
}
return props
}
// Return count of agents with reporter(agent) true
count(reporter) {
return this.reduce((prev, o) => prev + (reporter(o) ? 1 : 0), 0)
}
sum(key) {
return this.reduce((prev, o) => prev + (key ? o[key] : o), 0)
}
avg(key) {
return this.sum(key) / this.length
}
min(key) {
return this.reduce(
(prev, o) => Math.min(prev, key ? o[key] : o),
Infinity
)
}
max(key) {
return this.reduce(
(prev, o) => Math.max(prev, key ? o[key] : o),
-Infinity
)
}
extent(key) {
return [this.min(key), this.max(key)]
}
histogram(key, bins = 10, min = this.min(key), max = this.max(key)) {
const binSize = (max - min) / bins
const aa = new AgentArray(bins)
aa.fill(0)
this.ask(a => {
const val = key ? a[key] : a
if (val < min || val > max) {
util.warn(`histogram bounds error: ${val}: ${min}-${max}`)
} else {
let bin = Math.floor((val - min) / binSize)
if (bin === bins) bin-- // val is max, round down
aa[bin]++
}
})
// Object.assign(aa, {bins, min, max, binSize, key})
aa.parameters = { key, bins, min, max, binSize, arraySize: this.length }
// console.log(key, bins, min, max, binSize, aa)
return aa
}
/**
* Create copy of this AgentArray
* @returns AgentArray
*/
clone() {
return this.slice(0) // Returns an AgentArray rather than Array!
}
// Randomize the AgentArray in place. Use clone first if new AgentArray needed.
// Return "this" for chaining.
shuffle() {
return util.shuffle(this)
}
// Return this AgentArray sorted by the reporter in ascending/descending order.
// If reporter is a string, convert to a fcn returning that property.
// Use clone if you don't want to mutate this array.
/**
* Return this AgentArray sorted by the reporter in ascending/descending order.
* If reporter is a string, convert to a fcn returning that property.
*
* @param {function} reporter
* @param {boolean} [ascending=true]
* @returns {AgentArray}
*/
sortBy(reporter, ascending = true) {
util.sortObjs(this, reporter, ascending)
return this
}
// Remove an item from an array. Binary search if f given
// Array unchanged if item not found.
remove(o, f) {
const i = this.agentIndex(o, f)
if (i !== -1) {
this.splice(i, 1)
} else {
console.log(`remove: ${o.id} not in AgentArray`)
}
return this // chaining
}
insert(o, f) {
const i = this.sortedIndex(o, f)
if (this[i] === o) {
console.log(`insert: item ${o.id} already in AgentArray`)
return
}
this.splice(i, 0, o) // copyWithin?
}
// Binary search:
// Return array index of item, where array is sorted.
// If item not found, return index for item for array to remain sorted.
// f is used to return an integer for sorting, defaults to identity.
// If f is a string, it is the object property to sort by.
// Adapted from underscore's _.sortedIndex.
sortedIndex(item, f = util.identityFcn) {
if (util.isString(f)) f = util.propFcn(f)
const value = f(item)
// Why not array.length - 1? Because we can insert 1 after end of array.
// let [low, high] = [0, array.length]
let low = 0
let high = this.length
while (low < high) {
const mid = (low + high) >>> 1 // floor (low+high)/2
if (f(this[mid]) < value) {
low = mid + 1
} else {
high = mid
}
}
return low
}
// Return index of value in array with given property or -1 if not found.
// Binary search if property isnt null
// Property can be string or function.
// Use property = identity to compare objs directly.
agentIndex(item, property) {
if (!property) return this.indexOf(item)
const i = this.sortedIndex(item, property)
return this[i] === item ? i : -1
}
// True if item is in array. Binary search if f given
contains(item, f) {
return this.agentIndex(item, f) >= 0
}
// Return a random agent. Return undefined if empty.
oneOf() {
return util.oneOf(this)
}
// Return a random agent, not equal to agent
otherOneOf(agent) {
return util.otherOneOf(this, agent)
}
// Return n other random agents from this array
// otherNOf (n, agent) { return util.otherNOf(n, this, agent) }
otherNOf(n, item) {
if (this.length < n) throw Error('AgentArray: otherNOf: length < N')
return this.clone().remove(item).shuffle().slice(0, n)
}
// Return the first agent having the min/max of given value of f(agent).
// If reporter is a string, convert to a fcn returning that property
minOrMaxOf(min, reporter, valueToo = false) {
if (this.isEmpty()) throw Error('min/max OneOf: empty array')
if (typeof reporter === 'string') reporter = util.propFcn(reporter)
let o = null
let val = min ? Infinity : -Infinity
for (let i = 0; i < this.length; i++) {
const a = this[i]
const aval = reporter(a)
if ((min && aval < val) || (!min && aval > val)) {
;[o, val] = [a, aval]
}
}
return valueToo ? [o, val] : o
}
// The min version of the above
minOneOf(reporter) {
return this.minOrMaxOf(true, reporter)
}
// The max version of the above
maxOneOf(reporter) {
return this.minOrMaxOf(false, reporter)
}
// Like the pair above, but return both the object and its value in an array.
// const [obj, value] = minValOf(...)
minValOf(reporter) {
return this.minOrMaxOf(true, reporter, true)
}
maxValOf(reporter) {
return this.minOrMaxOf(false, reporter, true)
}
// Return n random agents as AgentArray.
// See [Fisher-Yates-Knuth shuffle](https://goo.gl/fWNFf)
// for better approach for large n.
nOf(n) {
if (n > this.length)
throw Error(`nOf: n larger than AgentArray: ${n} ${this.length}`)
if (n === this.length) return this
const result = new AgentArray()
while (result.length < n) {
const o = this.oneOf()
if (!(o in result)) result.push(o)
}
return result
}
// Return a new AgentArray of the n min/max agents of the value of reporter,
// in ascending order.
// If reporter is a string, convert to a fcn returning that property
// NOTE: we do not manage ties, see NetLogo docs.
minOrMaxNOf(min, n, reporter) {
if (n > this.length) {
throw Error('min/max nOf: n larger than AgentArray')
}
const as = this.clone().sortBy(reporter)
return min ? as.slice(0, n) : as.slice(as.length - n)
}
minNOf(n, reporter) {
return this.minOrMaxNOf(true, n, reporter)
}
maxNOf(n, reporter) {
return this.minOrMaxNOf(false, n, reporter)
}
}
// // Return shallow copy of a portion of this AgentArray
// // [See Array.slice](https://goo.gl/Ilgsok)
// // Default is to clone entire AgentArray
// cloneRange(begin = 0, end = this.length) {
// return this.slice(begin, end) // Returns an AgentArray rather than Array!
// }
export default AgentArray
</code></pre></article></section><footer class="footer" id="PeOAagUepe"><div class="wrapper">AgentScript version: 0.10.20 using clean-jsdoc-theme</div></footer></div></div></div><div class="search-container" id="PkfLWpAbet" style="display:none"><div class="wrapper" id="iCxFxjkHbP"><button class="icon-button search-close-button" id="VjLlGakifb" aria-label="close search"><svg><use xlink:href="#close-icon"></use></svg></button><div class="search-box-c"><svg><use xlink:href="#search-icon"></use></svg> <input type="text" id="vpcKVYIppa" class="search-input" placeholder="Search..." autofocus></div><div class="search-result-c" id="fWwVHRuDuN"><span class="search-result-c-text">Type anything to view search result</span></div></div></div><div class="mobile-menu-icon-container"><button class="icon-button" id="mobile-menu" data-isopen="false" aria-label="menu"><svg><use xlink:href="#menu-icon"></use></svg></button></div><div id="mobile-sidebar" class="mobile-sidebar-container"><div class="mobile-sidebar-wrapper"><a href="/" class="sidebar-title sidebar-title-anchor">Home</a><div class="mobile-nav-links"><div class="navbar-item"><a id="github-mobile" href="https://github.com/backspaces/agentscript" target="">Github</a></div><div class="navbar-item"><a id="AgentScript-mobile" href="https://code.agentscript.org" target="">AgentScript.org</a></div><div class="navbar-item"><a id="npm-mobile" href="https://www.npmjs.com/package/agentscript" target="">npm</a></div><div class="navbar-item"><a id="unpkg-mobile" href="https://unpkg.com/browse/agentscript/" target="">unpkg</a></div></div><div class="mobile-sidebar-items-c"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="AgentArray.html">AgentArray</a></div><div class="sidebar-section-children"><a href="AgentList.html">AgentList</a></div><div class="sidebar-section-children"><a href="AgentSet.html">AgentSet</a></div><div class="sidebar-section-children"><a href="Animator.html">Animator</a></div><div class="sidebar-section-children"><a href="DataSet.html">DataSet</a></div><div class="sidebar-section-children"><a href="GUI.html">GUI</a></div><div class="sidebar-section-children"><a href="GeoDataSet.html">GeoDataSet</a></div><div class="sidebar-section-children"><a href="Keyboard.html">Keyboard</a></div><div class="sidebar-section-children"><a href="Link.html">Link</a></div><div class="sidebar-section-children"><a href="Links.html">Links</a></div><div class="sidebar-section-children"><a href="Model.html">Model</a></div><div class="sidebar-section-children"><a href="Model3D.html">Model3D</a></div><div class="sidebar-section-children"><a href="Mouse.html">Mouse</a></div><div class="sidebar-section-children"><a href="Patch.html">Patch</a></div><div class="sidebar-section-children"><a href="Patches.html">Patches</a></div><div class="sidebar-section-children"><a href="RGBDataSet.html">RGBDataSet</a></div><div class="sidebar-section-children"><a href="ThreeDraw.html">ThreeDraw</a></div><div class="sidebar-section-children"><a href="Turtle.html">Turtle</a></div><div class="sidebar-section-children"><a href="Turtle3D.html">Turtle3D</a></div><div class="sidebar-section-children"><a href="Turtles.html">Turtles</a></div><div class="sidebar-section-children"><a href="TwoDraw.html">TwoDraw</a></div><div class="sidebar-section-children"><a href="World.html">World</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-src_geojson.html">src/geojson</a></div><div class="sidebar-section-children"><a href="module-src_gis.html">src/gis</a></div><div class="sidebar-section-children"><a href="module-src_utils.html">src/utils</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-tutorials"><div>Tutorials</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="tutorial-1 - AgentScript.html">1 - AgentScript</a></div><div class="sidebar-section-children"><a href="tutorial-2 - JavaScript.html">2 - JavaScript</a></div><div class="sidebar-section-children"><a href="tutorial-3 - Browser.html">3 - Browser</a></div><div class="sidebar-section-children"><a href="tutorial-4 - Model.html">4 - Model</a></div><div class="sidebar-section-children"><a href="tutorial-5 - View.html">5 - View</a></div><div class="sidebar-section-children"><a href="tutorial-6.1 - AnimatorController.html">6.1 - AnimatorController</a></div><div class="sidebar-section-children"><a href="tutorial-6.2 - KeyboardController.html">6.2 - KeyboardController</a></div><div class="sidebar-section-children"><a href="tutorial-6.3 - GuiController.html">6.3 - GuiController</a></div><div class="sidebar-section-children"><a href="tutorial-6.4 - MouseController.html">6.4 - MouseController</a></div><div class="sidebar-section-children"><a href="tutorial-7 - CodePenServer.html">7 - CodePenServer</a></div></div></div><div class="mobile-navbar-actions"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#light-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div></div></div><script type="text/javascript" src="scripts/core.min.js"></script><script src="scripts/search.min.js" defer="defer"></script><script src="scripts/third-party/fuse.js" defer="defer"></script><script type="text/javascript">var tocbotInstance=tocbot.init({tocSelector:"#eed4d2a0bfd64539bb9df78095dec881",contentSelector:".main-content",headingSelector:"h1, h2, h3",hasInnerContainers:!0,scrollContainer:".main-content",headingsOffset:130,onClick:bringLinkToView})</script></body></html>