如何操作网络中的元素table?

How to manipulate elements in a network table?

我正在尝试学习如何操纵 Netlogo tables。鉴于以下内容:

extensions [table]
globals [t]

to test
  set t table:make
  table:put t 1 [[50 1] [55 2]]
  table:put t 2 [[20 3] [15 4]]
  table:put t 3 [[35 4] [45 5] [50 6]]
end

产生以下 table:

1, 50, 1
1, 55, 2
2, 20, 3
2, 15, 4
3, 35, 4
3, 45, 5
3, 50, 6

请问我该如何做?

  1. 单独访问第一行中的值 50(或 table 中的任何其他单个值)?
  2. 访问值 50 和 55(即给定第一列(键)= 1,第 2 列中的所有值)?我可以得到这些作为列表吗?
  3. 一并删除第一行?
  4. 删除前两行(即删除 key = 1 的所有行)
  5. 添加一行:1、25、6

谢谢。

尽管名称 table 暗示了什么,但从行和列的角度来考虑它是一种误导。 table 扩展为您提供了一种数据结构,通常称为 "dictionary" 或 "hash map":它将键与值相关联。

在您的示例中,键是数字,值是数字列表的列表。以任何其他方式考虑它都有可能导致混淆。

话虽这么说,但您将如何完成所询问的操作:

; Access the value 50 in the first row (or any other
; single value in the table) on its own?
print first first table:get t 1

; Access the values 50 and 55 (i.e. all values in column 2 given
; the first column (the key) = 1)? Could I get these as a list?
print map first table:get t 1

; Delete the first row altogether?
table:put t 1 but-first table:get t 1
print t  

; Delete the first two rows (i.e delete all rows where the key = 1)
table:remove t 1
print t

; Add a row: 1, 25, 6
let current-list ifelse-value ((table:has-key? t 1) and (is-list? table:get t 1)) [
  table:get t 1
] [
  (list) ; empty list
]
table:put t 1 lput [25 6] current-list 
print t

结果:

50
[50 55]
{{table: [[1 [[55 2]]] [2 [[20 3] [15 4]]] [3 [[35 4] [45 5] [50 6]]]]}}
{{table: [[2 [[20 3] [15 4]]] [3 [[35 4] [45 5] [50 6]]]]}}
{{table: [[2 [[20 3] [15 4]]] [3 [[35 4] [45 5] [50 6]]] [1 [[25 6]]]]}}

请注意 none 这看起来像是在操纵行和列。

还要注意,对于最后一个操作,我检查是否已经有与键 1 关联的东西。在这种特殊情况下,不会有任何东西,因为我们只是删除了它,但代码显示了如何在需要时添加到现有列表。

最后,请注意,在添加回键 1 的条目后,它出现在 table 的末尾。 table 扩展按插入顺序维护其键,但您可能不应该依赖它。最好将数据结构视为无序的。从概念上讲,它是一个 集合 键与值相关联,集合没有特定的顺序。

回复评论:

What's the generic form of print map first table:get t 1, in order to get the values 1 and 2 (the 'column' 3 values when key=1)? print map item 0 table:get t 1 won't work. print map second table:get t 1 certainly won't work!

使用像 map first some-list 这样的表达式在一段时间后成为第二天性,但我往往会忘记它们并不是每个人都显而易见的。它正在使用 "concise syntax" 用于匿名过程(匿名过程在 NetLogo < 6.0 中曾被称为 "tasks")。

基本上:

map first table:get t 1

相当于:

map [ my-sublist -> first my-sublist ] table:get t 1

(这是 NetLogo 6.0.1 语法。)

更明确地说,map 是一个接受两个参数的报告原语:一个匿名报告者和一个列表。它将列表中的每一项传递给匿名报告者,并根据结果构建一个新列表。如果我们想要应用于我们的列表项的操作恰好是一个接受正确数量参数的报告者(在这种情况下,一个参数),我们可以将那个报告者的名字直接传递给 map 它会自动变成合适的匿名记者。举个不同的例子,map sqrt [4 9 16] 等同于 map [ n -> sqrt n ] [4 9 16].

现在你是对的,map item 1 table:get t 1 行不通。在这种情况下,我们需要使用普通语法:

map [ my-sublist -> item 1 my-sublist ] table:get t 1

有关详细信息,请参阅编程指南的 anonymous procedures 部分。

Is there a generic form of table:put t 1 but-first table:get t 1 that could delete the second or third 'row'?

let index 1 ; to remove the second item
table:put t 1 remove-item index table:get t 1