根据 Netlogo 中可变数量的组合过滤列表列表
Filtering a list of lists based on a variable number of combinations in Netlogo
假设我有一个要过滤的列表列表。该列表是这样的,在每个元素中,前两个字符串是内容
我要保留,第三个数字是它应该出现在过滤列表中的次数,而
最后一个元素是确定出现什么特定组合的列表的值。
这个想法是只保留每个列表中最有价值的 n 个项目,其中 n 是每个列表中的第三个元素,值为
由最后一项决定,而且,如果组合少于第三项,则尽可能多地保留。
因此,在下面的示例中,我希望只有第一个 "a"、"b" 组合,保留前两个 "a" "c",
并保留最后一个,(即使其中没有进一步的 "a" "d" 组合):
我一直在尝试使用过滤器的几种组合,并想过保留列表元素的方法,
没有成功解决这个特定问题。
to setup
let temp-example []
set temp-example [["a" "b" 1 5] ["a" "b" 1 3] ["a" "c" 2 4] ["a" "c" 2 2]
["a" "c" 2 1] ["a" "d" 4 1]]
end
所需的输出是以下列表:
[["a" "b" 1 5]["a" "c" 2 4]["a" "c" 2 2] ["a" "d" 4 1]]
我相信这里的一位重量级人物很快就会加入一两行解决方案,但现在我认为这可以满足您的需求。与这些记者:
to-report multifilter [ list_ ]
; Get the content pairs
let content-pairs remove-duplicates map [ i -> sublist i 0 2 ] list_
; Reorganize list into sublists for each content pair
let by-content-pairs map [ i -> filter [ j -> sublist j 0 2 = i ] list_ ] content-pairs
; Sort the sublists
let sorted-by-value map [ i -> sort-with 3 i ] by-content-pairs
; Keep only first n items of each sublist,
report reduce sentence map [ i -> keep-n 2 i ] sorted-by-value
end
to-report sort-with [ ind lst ]
; Sort the sublists by one of their indexed values
report sort-by [ [ a b ] -> ( item ind a ) > ( item ind b ) ] lst
end
to-report keep-n [ ind lst ]
; Keep only as many values as are passed by ind, or the length
; of the list, whichever value is smaller
let n item ind first lst
if n > length lst [
set n length lst
]
report sublist lst 0 n
end
使用您显示的格式在列表上调用 multifilter
,您应该会得到所需的输出:
to filter-multi
let temp-example [
["a" "b" 1 5] ["a" "b" 1 3] ["a" "c" 2 1]
["a" "c" 2 4] ["a" "c" 2 2] ["a" "d" 4 1]
]
print multifilter temp-example
end
输出:
[[a b 1 5] [a c 2 4] [a c 2 2] [a d 4 1]]
另一个例子:
to filter-multi
let temp-example [
["a" "b" 1 31] ["a" "b" 1 15] ["a" "b" 1 -53] ["a" "b" 1 10] ["a" "b" 1 3000]
["a" "c" 2 1] ["a" "c" 2 4] ["a" "c" 2 2] ["a" "c" 2 -10] ["a" "c" 2 14] ["a" "c" 2 40]
["a" "d" 4 1] ["a" "d" 4 12]
]
print multifilter temp-example
end
输出:
[[a b 1 3000] [a c 2 40] [a c 2 14] [a d 4 12] [a d 4 1]]
我认为这或多或少也回答了这个问题:
to-report frequency [an-item a-list]
report length (filter [ i -> i = an-item] a-list)
end
; Reporter to keep the n most valuable combinations
to-report take [n xs]
report sublist xs 0 min list n (length xs)
end
to go
set temp-1[]
set temp-2[]
set temp-3[]
set temp-4[]
foreach temp-example[[i] ->
set temp-1 lput (list item 0 i item 1 i) temp-1
set temp-2 lput item 2 i temp-2]
foreach temp-1[[j] ->
set temp-3 lput frequency j temp-1 temp-3
]
;First: obtain all existing combinations between the two letters:
foreach (range 0 (length temp-example)) [[j]->
ifelse item j temp-2 <= item j temp-3 [set temp-4 lput take (item j temp-2)
filter [i -> (list item 0 i item 1 i) = item j temp-1] temp-example temp-4];
[set temp-4 lput item j temp-example temp-4]; caso contrario, colocar so ate aos
item 2 j:
]
show remove-duplicates temp-4
end
假设我有一个要过滤的列表列表。该列表是这样的,在每个元素中,前两个字符串是内容 我要保留,第三个数字是它应该出现在过滤列表中的次数,而 最后一个元素是确定出现什么特定组合的列表的值。 这个想法是只保留每个列表中最有价值的 n 个项目,其中 n 是每个列表中的第三个元素,值为 由最后一项决定,而且,如果组合少于第三项,则尽可能多地保留。
因此,在下面的示例中,我希望只有第一个 "a"、"b" 组合,保留前两个 "a" "c", 并保留最后一个,(即使其中没有进一步的 "a" "d" 组合):
我一直在尝试使用过滤器的几种组合,并想过保留列表元素的方法, 没有成功解决这个特定问题。
to setup
let temp-example []
set temp-example [["a" "b" 1 5] ["a" "b" 1 3] ["a" "c" 2 4] ["a" "c" 2 2]
["a" "c" 2 1] ["a" "d" 4 1]]
end
所需的输出是以下列表:
[["a" "b" 1 5]["a" "c" 2 4]["a" "c" 2 2] ["a" "d" 4 1]]
我相信这里的一位重量级人物很快就会加入一两行解决方案,但现在我认为这可以满足您的需求。与这些记者:
to-report multifilter [ list_ ]
; Get the content pairs
let content-pairs remove-duplicates map [ i -> sublist i 0 2 ] list_
; Reorganize list into sublists for each content pair
let by-content-pairs map [ i -> filter [ j -> sublist j 0 2 = i ] list_ ] content-pairs
; Sort the sublists
let sorted-by-value map [ i -> sort-with 3 i ] by-content-pairs
; Keep only first n items of each sublist,
report reduce sentence map [ i -> keep-n 2 i ] sorted-by-value
end
to-report sort-with [ ind lst ]
; Sort the sublists by one of their indexed values
report sort-by [ [ a b ] -> ( item ind a ) > ( item ind b ) ] lst
end
to-report keep-n [ ind lst ]
; Keep only as many values as are passed by ind, or the length
; of the list, whichever value is smaller
let n item ind first lst
if n > length lst [
set n length lst
]
report sublist lst 0 n
end
使用您显示的格式在列表上调用 multifilter
,您应该会得到所需的输出:
to filter-multi
let temp-example [
["a" "b" 1 5] ["a" "b" 1 3] ["a" "c" 2 1]
["a" "c" 2 4] ["a" "c" 2 2] ["a" "d" 4 1]
]
print multifilter temp-example
end
输出:
[[a b 1 5] [a c 2 4] [a c 2 2] [a d 4 1]]
另一个例子:
to filter-multi
let temp-example [
["a" "b" 1 31] ["a" "b" 1 15] ["a" "b" 1 -53] ["a" "b" 1 10] ["a" "b" 1 3000]
["a" "c" 2 1] ["a" "c" 2 4] ["a" "c" 2 2] ["a" "c" 2 -10] ["a" "c" 2 14] ["a" "c" 2 40]
["a" "d" 4 1] ["a" "d" 4 12]
]
print multifilter temp-example
end
输出:
[[a b 1 3000] [a c 2 40] [a c 2 14] [a d 4 12] [a d 4 1]]
我认为这或多或少也回答了这个问题:
to-report frequency [an-item a-list]
report length (filter [ i -> i = an-item] a-list)
end
; Reporter to keep the n most valuable combinations
to-report take [n xs]
report sublist xs 0 min list n (length xs)
end
to go
set temp-1[]
set temp-2[]
set temp-3[]
set temp-4[]
foreach temp-example[[i] ->
set temp-1 lput (list item 0 i item 1 i) temp-1
set temp-2 lput item 2 i temp-2]
foreach temp-1[[j] ->
set temp-3 lput frequency j temp-1 temp-3
]
;First: obtain all existing combinations between the two letters:
foreach (range 0 (length temp-example)) [[j]->
ifelse item j temp-2 <= item j temp-3 [set temp-4 lput take (item j temp-2)
filter [i -> (list item 0 i item 1 i) = item j temp-1] temp-example temp-4];
[set temp-4 lput item j temp-example temp-4]; caso contrario, colocar so ate aos
item 2 j:
]
show remove-duplicates temp-4
end