Assemblyscript: Array#splice kann keine Elemente hinzufügen

Erstellt am 12. Okt. 2020  ·  5Kommentare  ·  Quelle: AssemblyScript/assemblyscript

Im normalen JavaScript:

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

Aber Signatur nur im AS:

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

Gibt es eine andere Möglichkeit, Daten in ein vorhandenes Array zu spleißen?

question

Alle 5 Kommentare

Derzeit kann AS keine variadischen Funktionen ausführen. Daher schlage ich diese Problemumgehung zum Einfügen neuer Elemente vor:

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 Glaubst du, dass wir das in der Zwischenzeit irgendwie in stdlib bereitstellen können? Wie ein spliceAndInsert , das ein Array anstelle von Restparametern nimmt?

Ich glaube nicht, dass ein Array von Einfügeelementen die richtige Lösung ist. Wie auch immer, wir haben viele andere Stellen, an denen variadische Funktionen benötigt werden, also fügen Sie besser einen geeigneten Mechanismus dafür hinzu, der im Compiler implementiert ist.

Vielen Dank @MaxGraey

insertAfter funktioniert etwas anders als angekündigt, es ist kein direkter Array-Ersatz, sondern es wird jedes Mal ein neues Array zugewiesen (zB realloc intern verwendet), also muss es neu zugewiesen werden:

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;
}

Und im Browser (mit einem modifizierten Loader-Skript, das getArray und getString exportiert):

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

Ja, festes Beispiel. Übrigens könntest du es verbessern mit __realloc und memory.copy

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen