2

Looking for a way to create object Array that has a fixed size of 3 that fills it with default values but when i come to push into the array it should replace the default values.

Example:

Declare an array which fills the array with a string of "default value"

["default value", "default value", "default value"]

I now push some text to this initial array and expect the following:

["Added Data", "Default value", "Default Value"]

I push more data to this array and expect the following:

["Added Data", "Added Data", "Default Value"]

Again I push more data to this array and expect the following:

["Added Data", "Added Data", "Added Data"]

So the end result should be if push one data then the remainder of array should remain the default value unless i push all three data into the array.

Note: This example is a string array just to show an example but the solution i am looking for is array of objects. The Array.fill() method works great for JavaScript immutable values like strings, numbers, and booleans. Array with objects, each slot in the array refers to the same object which is not what i am looking for. I want each object to be unique

hello world
  • 385
  • 5
  • 24
  • Array.fill but it references the same object as i am doing an array of objects – hello world Sep 15 '21 at 16:44
  • 1
    This addresses fixed length array: https://stackoverflow.com/questions/41139763/how-to-declare-a-fixed-length-array-in-typescript - but, doesn't address the array element substitution capability - you would need to build that on your own. – Randy Casburn Sep 15 '21 at 16:44
  • I don't think you can do this with a normal array. You'll need to create a custom class or function. – programmerRaj Sep 15 '21 at 16:46
  • 1
    Arrays don't work like this. You might consider a circular buffer: https://en.wikipedia.org/wiki/Circular_buffer – Matt Morgan Sep 15 '21 at 16:47
  • I suggest to implement your own implementation. One of the idea suggested on the second comment. – Eugene Sep 15 '21 at 16:49
  • @helloworld just want to note, this question has little to do with typescript. – hackape Sep 15 '21 at 16:51
  • That's not "`push`ing" elements onto an array, that's `unshift`ing elements onto an array. – I wrestled a bear once. Sep 15 '21 at 16:51
  • @hackape - but "fixed length arrays" does have everything to do with TypeScript - There is no such thing as a "fixed length array" in JavaScript - but in TypeScript arrays can be manipulated through typing enforcement - which also doesn't exist in JavaScript. But the OP is after a LIFO queue anyway - so it doesn't really matter. – Randy Casburn Sep 15 '21 at 16:55
  • I’m just saying OP might be one who doesn’t clearly understand the relationship between TS and JS. This is what I read from the context. I used to spend time explaining, some many times that I’m kinda tired of it. – hackape Sep 15 '21 at 17:14

3 Answers3

2

You can extend the Array class to make it have the behavior you described...

class FixedArray extends Array {

  /**
   * Contruct a fixed-length Array
   * @param int length - length of the array
   * @param mixed default_value - The default value for empty slots
   */
  constructor(length, default_value) {
    super(length);
    this.default_value = default_value;
    super.fill(default_value);
  }

  /**
   * "Push" items onto the begining of the array (unshift)
   * @params ...args mixed - values to put in the array
   */
  push(...args) {
    args.forEach(arg => {
      super.pop();
      super.unshift(arg);
    });
  }

  /**
   * Pop an item off the end of the array 
   * and replace it with the default value
   */
  pop(){
    super.pop();
    super.push(this.default_value);
  }

  /**
   * Shift an item off the start of the array 
   * and replace it with the default value
   */
  shift(){
    super.shift();
    super.unshift(this.default_value);
  }

}

var arr = new FixedArray(4, 'default value');
console.log(arr);

arr.push('new value');
console.log(arr);

arr.push('new value');
console.log(arr);

arr.pop();
console.log(arr);

And to address the part about the array's fill method, you cna add a method to just copy whatever value you put in it...

/**
 * Fill the array with copies of whatever arguments are provided.
 * Fills by value, not by reference.
 */
fill(...args){
  args.forEach(arg=>{
    let copy = JSON.parse(JSON.stringify(arg));
    this.push(arg);
  });
}

I wrestled a bear once.
  • 22,983
  • 19
  • 69
  • 116
1

For primitive data types' default value, follow below syntax

const numList = new Array(10).fill(0)

console.log(numList)
console.log('Total items: ' + numList.length)

For objects's default value, follow below syntax

const objList = new Array(10).fill(0).map(()=> ({ a: 1, b: 2 }))

console.log(objList)
console.log('Total items: ' + objList.length)
WasiF
  • 26,101
  • 16
  • 120
  • 128
0

To create and fill the array with default unique object value:

const tuple = new Array(3).fill(0).map(() => ({ foo: "bar" }))

// or
const defaultObject = { foo: "bar" }
const tuple = new Array(3).fill(0).map(() => ({ …defaultObject }))

To add new item, and keep array size constant

function addTo(tuple, newItem) {
  tuple.unshift(newItem) // add new item to beginning 
  tuple.pop() // remove old item at the end
}
hackape
  • 18,643
  • 2
  • 29
  • 57
  • That will only work if you're hard-coding the object that you want to fill it with. If you're trying to fill it with an object that is stored in a variable this will do exactly the same thing as just passing the variable to the fill method. – I wrestled a bear once. Sep 15 '21 at 17:15
  • the edit is an improvement, but any nested objects within that default object will still be passed by reference. – I wrestled a bear once. Sep 15 '21 at 17:18
  • Updated to make it more obvious. OP doesn’t want same ref, so `.fill` doesn’t work, that’s why I use `.map` – hackape Sep 15 '21 at 17:19
  • You’re welcome to edit my answer and improve it. You got enough rep. – hackape Sep 15 '21 at 17:21
  • I saw your update and responded to it. Editing answers isn't intended for changing the content of the answer, it's intended for things like reformatting. Besides, I already posted my own answer addressing this issue. – I wrestled a bear once. Sep 15 '21 at 17:22
  • Hmm, I didn’t know the norm. Thanks for the heads-up, but I’d like to leave it as-is. The thing I’d like to highlight is the fill-then-map trick, not trying to guard everything, otherwise you might also want to add try…catch in your answer. – hackape Sep 15 '21 at 17:28
  • 1
    I was leaving a note to identify an potential issue for future readers, not because I expected you to change something. Teaching people how to catch errors is waaay out of the scope of this question. – I wrestled a bear once. Sep 15 '21 at 17:31