2014-05-22 48 views
4

在J,I可以根據一些謂詞,像這樣的地方更新陣列的一個子集:將動詞應用於子數組,就地?

y (k}~) |. y {~ k =. I. '123' e.~ y =. '[1.2.3]' 
[3.2.1] 

我知道我可以分解出在這裏會合,但有一個更優雅的方式來做到這一點首先? 123只是一個例子。我想要做什麼,specificially是:

  • 獲得指數的陣列到陣列(k
  • 提取這些索引數組的項目進入一個新的陣列
  • 變換數組具有相同類型和形狀的新陣列
  • 將新陣列的值放回到插槽中。

此外,重要的是動詞作爲一個整體對數組進行操作,因爲我主要想要做的是置換並轉換子數組。 (因此在本例中爲)。

有沒有更簡單的方法來做到這一點?

回答

5

有這個更或多或少standard adverb

tweak =: (@:{) (`[) (`]) } 
    twist =: |. tweak 
    '123' ([email protected]:e.~ twist ]) '[1.2.3]' 
[3.2.1] 

這裏,tweak使用的}的動名詞形式到:

  1. 使用{陣列y選擇指數x
  2. 使用bonded bonded @{將變換函數應用於該[子]數組。也就是,{選擇,並且@:要求動詞適用於該選擇;扭曲以(反向)的形式提供該動詞。
  3. 在相同索引x(由[指示)將轉化的[子]陣列回填到原始陣列y(由]指示)。

我會注意到有兩件事情:

  1. 子陣列的修改是相當罕見的爲J,作爲語言鼓勵整體轉換。換句話說:數組的項目通常被認爲是同齡人,並且(通常)被平等對待。特別處理一些項目(指數)是不尋常的,需要更多的關注,特別是如果選擇是臨時的(而不是常規的,或遵循某種模式)。
  2. 「就地修改」是一個誤導性的術語,因爲(正如您正確指出的那樣),建立了一個新數組,並且這是修改的新數組。真正的就地修訂是可能的,但需要different approach(涉及名稱管理和/或顯式代碼)。
  3. 在您選擇的特定示例中存在一些認知失調:您的查找函數e.本質上是無序的,但您的轉換函數僅關注順序。本身沒有什麼不對,但是在重新排列數組部分的情況下可能會造成混淆(例如,考慮到y=.'[1.1.1]')。
2

Amenddoes exactly那。如果我在讀你的問題吧,下面是一個簡單的方法:

v1 =: [: I. e.~  NB. indeces 
v0 =: [: |. e.~ # ] NB. transform the subarray 
v2 =: ] 

'123' (v0`v1`v2) } '[1.2.3]' 
[3.2.1]