检查n维数组的内容是否有效

问题描述 投票:0回答:1

我正在尝试在打字稿中制作我自己的张量类(n 维数组)。 该类将其数据存储在一维数组属性中,并将数据的形状存储在单独的数组中,以便在索引数据时使用。

我想创建一个类似于

numpy.array
的函数,该函数将数据作为多维数组接收,将其元素存储为平面数组,然后提取形状。

但它还必须验证输入数组是否有效(我相信正确的短语是“具有均匀的形状”)

示例1

当函数给出以下输入时:

data = [
  [[1, 2], [3, 4]],
  [[5, 6], [7, 8]],
]

它应该返回一个形状为 (2, 2, 2) 和 [1, 2, 3, ..., 8] 元素的张量作为张量内数据的平面数组。

示例2

但是,当给出以下输入时:

data = [
  [[1], [3, 4]],
  [[5, 6], [7, 8]],
]

它应该失败,因为其中有一个子数组只包含一个 1 ,它与数组的其余部分不一致。

示例3

如果给出此输入:

data = [
  [[1], 2],
  [3, 4],
]

这也应该失败,不是因为 1 位于子数组内,该子数组也与数组的其余部分不一致。

numpy.array
函数似乎能够检测这些情况并相应地引发错误,我找不到有关可以检查此情况的算法的信息,也许我不知道要寻找什么,不胜感激。

注意:我意识到使用现有的库可能更好,可以做到这一点并继续,但这只是一个实验项目,我只是为了学习而做,我对此没有太多了解张量,所以如果您认为在实现这个之前我需要先学习其他东西,那么我将不胜感激。

arrays typescript numpy tensor
1个回答
1
投票

这可能效率非常低,但它适用于实验项目。输出包含一个额外的维度“0”,因为这是内部维度。要么删除该数组的第一个元素,要么处理这种情况,但对我来说,数字可以被视为维度为零的数组似乎是合理的。

/// arraysEqual taken from https://stackoverflow.com/questions/3115982/how-to-check-if-two-arrays-are-equal-with-javascript
function arraysEqual(a: any[], b: any[]) {
  if (a === b) return true;
  if (a == null || b == null) return false;
  if (a.length !== b.length) return false;

  // If you don't care about the order of the elements inside
  // the array, you should sort both arrays here.
  // Please note that calling sort on an array will modify that array.
  // you might want to clone your array first.

  for (var i = 0; i < a.length; ++i) {
    if (a[i] !== b[i]) return false;
  }
  return true;
}

function testArray(x: any): [number[], number[]] {
  if (Array.isArray(x)) {
    let lastDim: number[] | undefined = undefined;
    let numbers: number[] = [];
    if (x.length === 0) {
      throw "Empty array";
    }
    for (const el of x) {
      const [d, n] = testArray(el);
      if (lastDim === undefined) {
        lastDim = d;
      }

      if (!arraysEqual(lastDim, d)) {
        throw "Dimensions not equal";
      }
      numbers.push(...n);
    }
    if (lastDim === undefined) {
      throw "Should never happen, but this line makes typescript happy :)";
    }
    lastDim.push(x.length);
    return [lastDim, numbers];
  } else if (typeof x === "number") {
    return [[0], [x]];
  } else {
    throw "Not an array or a number";
  }
}

const data1 = [
  [
    [1, 2],
    [3, 4],
  ],
  [
    [5, 6],
    [7, 8],
  ],
];

console.log(testArray(data1));

const data2 = [
  [[1], [3, 4]],
  [
    [5, 6],
    [7, 8],
  ],
];

try {
  console.log(testArray(data2));
} catch (e) {
  console.error(e);
}

const data3 = [
  [[1], 2],
  [3, 4],
];

try {
  console.log(testArray(data3));
} catch (e) {
  console.error(e);
}

[LOG]: [[0, 2, 2, 2], [1, 2, 3, 4, 5, 6, 7, 8]] 
[ERR]: "Dimensions not equal" 
[ERR]: "Dimensions not equal" 
© www.soinside.com 2019 - 2024. All rights reserved.