Assemblyscript: Array#splice can't add elements

Created on 12 Oct 2020  ·  5Comments  ·  Source: AssemblyScript/assemblyscript

In normal JavaScript:

fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(2, 0, "Lemon", "Kiwi");
fruits // == ["Banana", "Orange", "Lemon", "Kiwi", "Apple", "Mango"]

But signature in AS only:

function splice(start: i32, deleteCount?: i32): Array<T>

Any other way to splice data into existing array?

question

All 5 comments

Currently AS can't do variadic functions. So I propose this workaround for inserting new item(s):

export function insertAfter<T>(arr: T[], index: i32, value: T): T[] {
  const len = arr.length + 1
  const res = new Array<T>(len)
  if (index < 0) index = len + index - 1
  if (index > len) index = len - 1
  let i = 0
  while (i < index) res[i] = arr[i++] // or use memory.copy
  res[i++] = value
  while (i < len) res[i] = arr[i++ - 1] // or use memory.copy
  return res
}

// intead fruits.splice(2, 0, "Lemon", "Kiwi") use:
fruits = insertAfter(fruits, 2, "Lemon");
fruits = insertAfter(fruits, 3, "Kiwi");

@MaxGraey Do you think that we can provide this for the meantime in stdlib somehow? Like a spliceAndInsert taking an array instead of rest params?

I don't think array of insert items is proper solution. Anyway we have a lot of other places where need variadic functions so better add proper mechanism for this implemented in compiler.

Thank you a lot @MaxGraey

insertAfter works a bit different than advertised, it is not in-place array replacement, but allocating a new array every time (e.g. not using realloc internally), so it needs reassignment:

import {insertAfter} from "./insertAfter";

export function example(): string[] {
    var fruits = ["Banana", "Orange", "Apple", "Mango"];
    fruits = insertAfter(fruits, 2, "Lemon");
    fruits = insertAfter(fruits, 3, "Kiwi");
    return fruits;
}

And in browser (with a modified Loader script which exports getArray and getString):

fruits_ptr = assemblyscript.module.exports.example()
// 21359280
fruits = Loader.getArray(fruits_ptr)
// (6) [1152, 1184, 1312, 1616, 1216, 1248]
fruits.map(Loader.getString)
// (6) ["Banana", "Orange", "Lemon", "Kiwi", "Apple", "Mango"]

image

Yes, fixed example. Btw you could improve it using __realloc and memory.copy

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DuncanUszkay1 picture DuncanUszkay1  ·  3Comments

MaxGraey picture MaxGraey  ·  4Comments

kyegupov picture kyegupov  ·  3Comments

evgenykuzyakov picture evgenykuzyakov  ·  3Comments

vladimir-tikhonov picture vladimir-tikhonov  ·  4Comments