0

Via XMLHttpRequest I have received arraybuffer of Uint32 values

oReq.onload = function (oEvent) {
  var arrayBuffer = oReq.response; 
  if (arrayBuffer) {
    pointsArray = new Uint32Array(arrayBuffer);

However, I know that this array has an internal structure. Say, pointsArray length is 10 but I know it contains 5 points X,Y coordinates.

How can I create( hopefully without copy ) two new 'views' at this pointsArray so that I can index X and Y points separately?

Something like:

var xArray = something (pointsArray)
var yArray = something else (pointsArray)

Then, even if pointsArray length is 10, my new two arrays will have a length of 5 so I can index them from 0 to 4.

EDIT: The question is imprecise. It implies that original input array can't be modified so the answer by David Alvarez is correct, despite the stated preference for avoiding any copies, which, in turn, for the best performance may require the format of the input array to be modified.

Tony
  • 1,566
  • 2
  • 15
  • 27
  • loop through it and turn into whatever format you want ? – Muhammad Usman Feb 22 '20 at 21:17
  • I can loop but that means I have to make extra calculations on indices/elements sizes. If JavaScript has an approach without me doing it, I would like to know about it. Also, I am not clear, even if I do that, that I won't incur unnecessary copies when I create two separate arrays for X and Y. Basically, I would like not to have to create two new arrays in code via for loop construct, if possible. – Tony Feb 22 '20 at 21:23
  • What is the structure of the array ? [x1,y1,x2,y2] or [x1,x2,y1,y2] ? – David Alvarez Feb 22 '20 at 21:23
  • [x1,y1,x2,y2,x3,y3, ...] – Tony Feb 22 '20 at 21:25
  • https://stackoverflow.com/questions/22464605/convert-a-1d-array-to-2d-array – JGFMK Feb 22 '20 at 21:28

2 Answers2

2

If there are 5 consecutive X coordinates and then 5 consecutive Y coordinates, you can create arrays on the same buffer:

let xArray = new Uint32Array(arrayBuffer,0,5);
let yArray = new Uint32Array(arrayBuffer,5*4,5);

(where 4 could be Uint32Array.BYTES_PER_ELEMENT)

But otherwise you will have to copy elements around, at least inside the array.

Side note: TypedArrays use platform-native byte order, so generally you can not avoid dealing with all data elements, at least in a conditional branch swapping bytes if necessary, or you can use DataView.getUint32(bytOffset,littleEndian) and you are back on the starting field, accessing elements individually.

tevemadar
  • 12,389
  • 3
  • 21
  • 49
1

What you can do is create functions.

const xArray = () => pointsArray.filter((element, index) => index % 2 === 0)
const yArray = () => pointsArray.filter((element, index) => index % 2 !== 0)

In that manner, no values will be copied or processed until you call xArray() or yArray(). That is what I think is the closest to a "view".

EDIT

If you want to use that "view" to directly access nth element:

const nthX = (n) => pointsArray.filter((element, index) => index % 2 === 0)[n]
const nthY = (n) => pointsArray.filter((element, index) => index % 2 !== 0)[n]

Then call nthX(2) if you want the x at the index 2 (of the array contianing all the x's)

EDIT 2

If you want the same behavior without copying the array you can do:

const nthX = (n) => pointsArray[n*2]
const nthY = (n) => pointsArray[n*2+1]
David Alvarez
  • 1,226
  • 11
  • 23
  • Where do I specify index when calling xArray or yArray? – Tony Feb 22 '20 at 22:34
  • You do not specify it. You just call xArray(), this will call pointsArray.filter(filterFunction). And filterFunction has this shape : function filterFunction(currentElement, indexOfCurrentElement) { // the element is returned if the function returns true }. More info here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter#Syntax – David Alvarez Feb 22 '20 at 22:57
  • And here I directly passed the function returning even indexes for x and not even indeses for y (as you can see with the modulo) – David Alvarez Feb 22 '20 at 23:00
  • I don't get it. How do I get x coordinate of a point at index 3, for example? Say I have code like var x3 = something What is something in this case? – Tony Feb 22 '20 at 23:10
  • No, xArray() is an array containing all your x's. If you want to use the 3rd x, then call `xArray()[2]` – David Alvarez Feb 22 '20 at 23:26
  • Ok, I think I get it. However per docs it creates a new typed array so there is a copy implied. – Tony Feb 22 '20 at 23:33
  • Yes but why do you want to absolutely avoid copy ? – David Alvarez Feb 22 '20 at 23:38
  • Cause I am worried because I have too many elements in the original array to start with, so making 2 new copies of x,y subarrays is worrysome. However, since I haven't conditioned an answer on that (just made the non-copying answer preferred) your answer is correct and works. Thank you. – Tony Feb 22 '20 at 23:43
  • Look at my edits I made a version without copy :) @Tony – David Alvarez Feb 23 '20 at 00:05
  • While I have a feeling :) that the other answer may be more performant, I can't deny this is so far the most correct answer, given the question. I'll accept it after giving it some time to maybe someone else chime in. – Tony Feb 23 '20 at 00:24