=============== Summary ===============
Change Set: withDoEnhanced
Date: 21 February 2024
Author: Christoph Thiede
Improves support for #with:do: and friends:
* On Matrix, enforces the other matrix to have same shape as the receiver. Previously, additional rows/columns were ignored. This breaking change aligns the behavior with that of SequenceableCollection>>with:do:.
* Implements and tests #with:do:, #with:collect:, #withKeysValuesAnd:do:, and #withKeysValuesAnd:collect: on Dictionary.
* Adds support for arithmetic operations between multiple dictionaries.
Example:
{JsonObject new likes: 12; shares: 7; yourself.
JsonObject new likes: 4; shares: 3; yourself}
average. --> a JsonObject(#likes->8 #shares->5)
* Implements #@ on Matrix.
Example:
(Matrix rows: 2 columns: 2 contents: #(1 2 3 4)) @ (Matrix ones: 2) --> a Matrix(1@1 2@1 3@1 4@1)
=============== Diff ===============
Collection>>adaptToCollection:andSend: {adapting} · ct 2/21/2024 12:53 (changed)
adaptToCollection: rcvr andSend: selector
"If I am involved in arithmetic with another Collection, return a Collection of
the results of each element combined with the scalar in that expression."
- rcvr isSequenceable & self isSequenceable ifFalse:
- [self error: 'Only sequenceable collections may be combined arithmetically'].
+ ((rcvr isSequenceable and: [self isSequenceable]) or: [rcvr isDictionary and: [self isDictionary]]) ifFalse:
+ [self error: 'Only sequenceable collections or dictionaries may be combined arithmetically'].
^ rcvr with: self collect:
[:rcvrElement :myElement | rcvrElement perform: selector with: myElement]
Dictionary>>isOfSameSizeCheck: {private} · ct 2/21/2024 12:54
+ isOfSameSizeCheck: otherDictionary
+
+ (otherDictionary keys = self keys) ifFalse: [self errorDifferentSize].
Dictionary>>with:collect: {enumerating} · ct 2/21/2024 13:04
+ with: otherDictionary collect: twoArgBlock
+ "Collect and return the result of evaluating twoArgBlock with corresponding values from the receiver and otherDictionary."
+
+ | result |
+ self isOfSameSizeCheck: otherDictionary.
+ result := self species new: self size.
+ self keysAndValuesDo: [:key :value |
+ result at: key put:
+ (twoArgBlock
+ value: value
+ value: (otherDictionary at: key))].
+ ^ result
Dictionary>>with:do: {enumerating} · ct 2/21/2024 13:02
+ with: otherDictionary do: twoArgBlock
+ "Evaluate twoArgBlock with corresponding values from the receiver and otherDictionary."
+
+ self isOfSameSizeCheck: otherDictionary.
+ self keysAndValuesDo: [:key :value |
+ twoArgBlock
+ value: value
+ value: (otherDictionary at: key)].
Dictionary>>withKeysValuesAnd:collect: {enumerating} · ct 2/21/2024 13:03
+ withKeysValuesAnd: otherDictionary collect: threeArgBlock
+ "Collect and return the result of evaluating threeArgBlock with keys and values from the receiver and corresponding values from otherDictionary."
+
+ | result |
+ self isOfSameSizeCheck: otherDictionary.
+ result := self species new: self size.
+ self keysAndValuesDo: [:key :value |
+ result at: key put:
+ (threeArgBlock
+ value: key
+ value: value
+ value: (otherDictionary at: key))].
+ ^ result
Dictionary>>withKeysValuesAnd:do: {enumerating} · ct 2/21/2024 13:03
+ withKeysValuesAnd: otherDictionary do: threeArgBlock
+ "Evaluate threeArgBlock with corresponding values from the receiver and otherDictionary."
+
+ self isOfSameSizeCheck: otherDictionary.
+ self keysAndValuesDo: [:key :value |
+ threeArgBlock
+ value: key
+ value: value
+ value: (otherDictionary at: key)].
DictionaryTest>>testPlus {tests - arithmetic} · ct 2/21/2024 13:16
+ testPlus
+
+ | dict1 dict2 |
+ dict1 := Dictionary new.
+ dict1 at: #a put: 1; at: #b put: 2.
+
+ dict2 := Dictionary new.
+ dict2 at: #a put: 10; at: #b put: 20.
+
+ self
+ assert: (Dictionary new at: #a put: 11; at: #b put: 22; yourself)
+ equals: dict1 + dict2.
DictionaryTest>>testWithCollect {tests - enumerating} · ct 2/21/2024 13:15
+ testWithCollect
+
+ | dict1 dict2 |
+ dict1 := Dictionary new.
+ dict1 at: #a put: 1; at: #b put: 2.
+
+ dict2 := Dictionary new.
+ dict2 at: #a put: 10; at: #c put: 30.
+
+ self
+ should: [dict1 with: dict2 collect: [:a :b | ]]
+ raise: Error.
+
+ dict2 := Dictionary new.
+ dict2 at: #a put: 10; at: #b put: 20.
+ self
+ assert: (Dictionary new at: #a put: 11; at: #b put: 22; yourself)
+ equals: (dict1 with: dict2 collect: [:a :b | a + b]).
DictionaryTest>>testWithDo {tests - enumerating} · ct 2/21/2024 13:15
+ testWithDo
+
+ | dict1 dict2 |
+ dict1 := Dictionary new.
+ dict1 at: #a put: 1; at: #b put: 2.
+
+ dict2 := Dictionary new.
+ dict2 at: #a put: -1; at: #c put: -3.
+
+ self
+ should: [dict1 with: dict2 do: [:a :b | ]]
+ raise: Error.
+
+ dict2 := Dictionary new.
+ dict2 at: #a put: -1; at: #b put: -2.
+ dict1 with: dict2 do: [:pos :neg |
+ self assert: (dict1 at: (dict2 keyAtValue: neg)) equals: neg negated.
+ self assert: (dict2 at: (dict1 keyAtValue: pos)) equals: pos negated].
DictionaryTest>>testWithKeysAndValuesAndCollect {tests - enumerating} · ct 2/21/2024 13:15
+ testWithKeysAndValuesAndCollect
+
+ | dict1 dict2 |
+ dict1 := Dictionary new.
+ dict1 at: #a put: 1; at: #b put: 2.
+
+ dict2 := Dictionary new.
+ dict2 at: #a put: 10; at: #c put: 30.
+
+ self
+ should: [dict1 withKeysValuesAnd: dict2 collect: [:key :a :b | ]]
+ raise: Error.
+
+ dict2 := Dictionary new.
+ dict2 at: #a put: 10; at: #b put: 20.
+ self
+ assert: (Dictionary new at: #a put: #(a 11); at: #b put: #(b 22); yourself)
+ equals: (dict1 withKeysValuesAnd: dict2 collect: [:key :a :b | {key. a + b}]).
DictionaryTest>>testWithKeysValuesAndDo {tests - enumerating} · ct 2/21/2024 13:15
+ testWithKeysValuesAndDo
+
+ | dict1 dict2 |
+ dict1 := Dictionary new.
+ dict1 at: #a put: 1; at: #b put: 2.
+
+ dict2 := Dictionary new.
+ dict2 at: #a put: -1; at: #c put: -3.
+
+ self
+ should: [dict1 withKeysValuesAnd: dict2 do: [:a :b | ]]
+ raise: Error.
+
+ dict2 := Dictionary new.
+ dict2 at: #a put: -1; at: #b put: -2.
+ dict1 withKeysValuesAnd: dict2 do: [:key :pos :neg |
+ self assert: pos equals: (dict1 at: key).
+ self assert: neg equals: (dict2 at: key).
+ self assert: neg negated equals: (dict1 at: (dict2 keyAtValue: neg)).
+ self assert: pos negated equals: (dict2 at: (dict1 keyAtValue: pos))].
Matrix>>@ {arithmetic} · ct 2/21/2024 12:47
+ @ aCollection
+ ^ self with: aCollection collect: [:a :b | a @ b]
Matrix>>isOfSameSizeCheck: {private} · ct 2/21/2024 12:39
+ isOfSameSizeCheck: otherMatrix
+
+ (otherMatrix rowCount = self rowCount and: [otherMatrix columnCount = self columnCount]) ifFalse: [self errorDifferentSize].
Matrix>>with:collect: {enumerating} · ct 2/21/2024 12:38 (changed)
- with: aCollection collect: aBlock
- "aCollection must support #at:at: and be at least as large as the receiver."
+ with: otherMatrix collect: aBlock
+ self isOfSameSizeCheck: otherMatrix.
^self withIndicesCollect: [:each :row :column |
- aBlock value: each value: (aCollection at: row at: column)]
+ aBlock value: each value: (otherMatrix at: row at: column)]
Matrix>>with:do: {enumerating} · ct 2/21/2024 12:39 (changed)
- with: aCollection do: aBlock
- "aCollection must support #at:at: and be at least as large as the receiver."
+ with: otherMatrix do: aBlock
+ self isOfSameSizeCheck: otherMatrix.
self withIndicesDo: [:each :row :column |
- aBlock value: each value: (aCollection at: row at: column)].
+ aBlock value: each value: (otherMatrix at: row at: column)].
Matrix>>with:inject:into: {enumerating} · ct 2/21/2024 12:40 (changed)
- with: aCollection inject: startingValue into: aBlock
- "aCollection must support #at:at: and be at least as large as the receiver."
+ with: otherMatrix inject: startingValue into: aBlock
+ self isOfSameSizeCheck: otherMatrix.
^self withIndicesInject: startingValue into: [:value :each :row :column |
- aBlock value: value value: each value: (aCollection at: row at: column)]
+ aBlock value: value value: each value: (otherMatrix at: row at: column)]
Object class>>releaseNotes {documentation} · ct 2/21/2024 13:37 (changed)
releaseNotes
"This is a scratch pad of release notes for the 6.0 release this version is building towards.
Feel free to add to this comment mention of things that should appear in the release notes.
- <tbd>"
+ * Matrix>>with:do:, Matrix>>with:collect:, and Matrix>>with:inject:into: no longer tolerate the other matrix to be larger than the receiver."
self error: 'comment only'
---
Sent from Squeak Inbox Talk
["withDoEnhanced.1.cs"]