问题描述
如果我有这样的列表:
let m [["a" 1]["a" 5]["b" 3]["b" 7]["c" 1]]
产生[["a" 6]["b" 10]["c" 1]]
的正确语法是什么?
我已经尝试过了,但是我总是得到ERROR: Expected a variable name here
。
reduce [[[x y ][ x z ]] -> [ x y + z ]] m
谢谢。
解决方法
我看到您尝试了foreach来作为答案,而不是编辑问题。看来您已经解决了,做得很好。但是我认为我应该使用相同的逻辑但使用新的列表语法来提供一个版本。您正在使用v5,而v6中的列表语法已发生重大变化。我还使用first
和其他类似的关键字来提高可读性。
这是一个独立的模型,您可以将其放入一个空的NetLogo会话中,然后运行“ testme”过程以查看其工作原理。
to testme
let m [["a" 1]["a" 5]["b" 2]["c" 5]["b" 3]["b" 7]["c" 1]]
print m
print aggregate-lol m
end
to-report aggregate-lol [#li]
; sort the list alphabetically on first of pair
let the-list sort-by [[a b] -> first a < first b] #li
; prime the loop
let now-letter first first the-list
let add-pair first the-list
let result []
; loop from the second item to the end
foreach butfirst the-list
[ this-pair ->
ifelse first this-pair = now-letter
; in same group so add
[ set add-pair (list first add-pair (last add-pair + last this-pair)) ]
; in different group so output and use this item as start of next group
[ set result lput add-pair result
set add-pair this-pair
set now-letter first this-pair
]
]
; append the final pair
set result lput add-pair result
report result
end
只需在命令中心键入print aggregate-lol [["a" 1]["a" 5]["b" 2]["c" 5]["b" 3]["b" 7]["c" 1]]
之类的命令,它也可以正常工作。
这里是使用有效列表基元的替代方法(密集代码,相当不可读)。请注意,map
本质上是通过对给定列表中的每个项目应用函数并根据结果构造列表来完成foreach
在原始结构中的工作。 filter
选择所需的列表项(与第一个字母匹配)。
to-report aggregate-dense [#li]
; list of unique first letters
let all-firsts remove-duplicates map [ll -> first ll] #li
; by first letters,filter,sum and construct pair into list
report map [ ff ->
(list ff sum map [ll -> last ll] filter [ii -> first ii = ff] #li)
] all-firsts
end
,
编辑:@JenB对这个答案here做出了一个修订的,更清晰的版本,并被接受为最终答案。
这里的MVP(最有价值的过程)是item
,因为列表还包含列表。
为了获得想要的列表,这些是必须要做的事情:
- 按字母顺序()对列表列表进行排序
- 根据字母求和。
要做第一点:
globals [the_list]
set the_list report sort-by [[a b] -> item 0 a < item 0 b] m
第二点:
to-report aggregate-lol [li]
let result []
let first_item item 0 li ; first_item is also a list
let li-length length li
let li-end li-length - 1
foreach (range 1 li-length)
[ ? -> ifelse ? != li-end
[ ifelse item 0 item ? li = item 0 first_item
[ set first_item replace-item 1 first_item (item 1 first_item + item 1 item ? li) ]
[ set result lput first_item result
set first_item item ? li ]
]
[ ifelse item 0 item ? li = item 0 first_item
[ set first_item replace-item 1 first_item (item 1 first_item + item 1 item ? li)
set result lput first_item result ]
[ set result lput first_item result
set result lput item li-end li result ]
]
]
report result
end
结果将是
show aggregate-lol the_list