Ninox 中的陣列

簡單陣列

操作文字或數字陣列相當直接:

var myArray := ["a", "b", "d"];

index(myArray, "b");
myArray := array(myArray, ["c"]);

myArray order this;

對於文字或數字陣列,也可以用 ordersortunsort 來排序。
更多與陣列相關的函式,請參閱 Ninox 官方文件

二維陣列

Ninox 並不直接支援二維陣列。取而代之的做法是使用 JSON 物件組成的陣列。
例如,依 d2 欄位的第二個元素為陣列排序:

var myArray := [{'d2':["a", "Z"]}, {'d2':["b", "B"]}, {'d2':["c", "C"]}, {'d2':["d", "D"]}];

(myArray order by item('d2', 1));

這段程式碼回傳:[{"d2":["b","B"]},{"d2":["c","C"]},{"d2":["d","D"]},{"d2":["a","Z"]}]

篩選陣列

您可以像篩選 select 的結果一樣篩選陣列。對於文字或數字陣列,用 this 來指涉正在被篩選的值:

var myArray := ["Jan", "Fred", "Jacques"];
myArray[this like "J"] order this;

對於 JSON 陣列,則直接使用鍵名:

var myArray := [
  { 'prénom' : "Jan", nom : "Augustin" },
  { 'prénom' : "Fred", nom : "Baillot" },
  { 'prénom' : "Jacques", nom : "Tur" }
];

myArray[nom like "i"] order 'prénom';

這段程式碼回傳一個 JSON 陣列:[{"prénom":"Fred","nom":"Baillot"}, {"prénom":"Jan","nom":"Augustin"}]

對 JSON 陣列做自訂運算

對於 JSON 陣列,您可以加入一段程式碼區塊(放在括號中),為每一次疊代執行自訂運算。就像 for in 一樣,結果陣列的型別取決於區塊中的最後一行程式碼。

範例:計算全名(prénom + nom)的長度:

var myArray := [
  { 'prénom' : "Leo", nom : "Martin" },
  { 'prénom' : "Paul", nom : "Garnet" },
  { 'prénom' : "Pierre", nom : "Dur" }
];

var nameLengths := myArray[nom like "a"].(
    var fullName := ---{'prénom'} {nom}---;
    length(fullName)
);
nameLengths;

這段程式碼回傳一個數字陣列 [10, 11],代表這些全名的長度。

初始化一個空的具型別陣列

在 Ninox 中,要建立一個空的、但仍帶有正確記錄型別的陣列,慣用的訣竅是執行一個以 where false 過濾的 select
這個查詢回傳零筆記錄,卻保留了陣列元素的型別。

"Empty Invoice Item array:";
let t := (select 'Invoice Item' where false);
  • t 現在是一個陣列,其元素為 Invoice Item 型別。
  • 因為它既是空的又具型別,可以放心當作 array() 運算的起點重複使用。

為什麼不直接用 []

字面值 []無型別的陣列。它通常也能用,但當它與記錄集合上的 array() 搭配時,Ninox 可能會抱怨型別不一致。
select … where false 這個寫法則完全避開了這個問題。

為基本型別(數字、文字、JSON⋯⋯)建立空陣列

當您需要一個裝純量值的空陣列——數字、文字字串或 JSON 物件——並沒有可供 select 的底層表格。
不過您仍然可以取得一個具型別的空陣列:先在 [] 中放一個假元素當種子,再立刻把它篩掉:

"Empty number / text / JSON array:";
let t := [1][false];   "t is now an empty but number typed array";

[1] 產生一個只有一個元素的數字陣列;[false] 這個篩選器把該元素移除,留下一個仍保有數字型別的空陣列。
若您需要文字或 JSON 型別,就把 1 換成文字或 JSON 字面值。

把二維陣列攤平

每一筆 Invoice 都含有自己的 Invoice Items 子陣列。若要取得一份單一清單,涵蓋所有發票的全部項目,就逐一走訪這些發票,把它們的子陣列串接起來。

"Initialize empty array:";
let t := (select 'Invoice Item' where false);

"Iterate over each invoice and add its items:";
for i in Invoices do
    t := array(t, i.'Invoice Items')
end;

"Return the flattened list:";
t

運作方式

  1. for i in Invoices do … end 走訪每一筆 Invoice 記錄。
  2. array(t, i.'Invoice Items')t 目前的值與該筆發票內項目的陣列串接起來。
    • 第一次疊代時,加入第一筆發票的項目。
    • 第二次疊代時,加入第二筆發票的項目,依此類推。
  3. 迴圈結束後,t 就在單一個扁平陣列中裝著所有發票的所有項目。

現在您可以對它做各種操作,例如用 count(t) 得知項目總數,或直接對 t 進行迴圈或篩選。