我有一个像
这样的字符串数组#(#('smalltalk' 'pharo' 'cool')
#('smalltalk' 'pharo' 'new')
#('smalltalk' 'cool'))
并且想要计算不同系列中Strings的共同发生量,所以我会得到以下信息:
smalltalk,pharo,2
smalltalk,cool,2
smalltalk,new,1
pharo,cool,1
pharo,new,1
cool,new,0(0次出现是可选的)
最惯用的使用Smalltalk(Pharo的)收集方法来收集这些数据是什么? (结果可以存储在一些带有element1,element2和count变量的简单对象中。)
我可以提出一些简单的解决方案,但与过去类似的问题一样,我发现,我错过了一个漂亮的Smalltalk解决方案,而是做了一些愚蠢的循环。
答案 0 :(得分:4)
这也给出了相反的情况,但我很好 它看起来非常清晰,现在的问题是,如果效率很高:
|source bagOfPairs|
source := #(#('smalltalk' 'pharo' 'cool')
#('smalltalk' 'pharo' 'new')
#('smalltalk' 'cool')).
bagOfPairs := Bag new.
source do: [ :each |
each allPairsDo: [:first :second |
(first = second) ifFalse: [bagOfPairs add: {first . second}]
].
].
bagOfPairs inspect.
答案 1 :(得分:2)
我没有看到任何惯用语,这是一个相对复杂的操作,我会分解成这些操作(原型代码):
countAssociatedPairsIn aCollection
| set pairs |
set := aCollection flattenAllElementsInto: Set new.
pairs := set generateAllPairs.
^pairs collect: [:pair | pair -> (aCollection count: [:associations | associations includesAll: pair])]
如果你想按计数排序,那么它只是另一个sortedBy:#value
如果你只是打印而不是收集:,你可以在do:
中打开一些循环仍然需要实现flattenAllElementsInto :(简单,像扁平的asSet)和generateAllPairs(或某种allPairsDo:如果你只是打印,有SequenceableCollection>> #combinations:atATimeDo:这对于这个任务来说很方便)。
countAssociatedPairsIn aCollection
| items |
items:= aCollection flattened asSet asArray sorted.
items combinations: 2 atATimeDo: [:pair |
Transcript cr;
print: pair; nextPutAll: '->';
print: (aCollection count: [:associations | associations includesAll: pair]);
flush]