Browse Source

Collection >> {none,any,all}Satisfy:

Herbert Vojčík 11 years ago
parent
commit
d726202146
4 changed files with 235 additions and 61 deletions
  1. 88 14
      js/Kernel-Collections.js
  2. 97 34
      js/Kernel-Tests.js
  3. 28 6
      st/Kernel-Collections.st
  4. 22 7
      st/Kernel-Tests.st

+ 88 - 14
js/Kernel-Collections.js

@@ -209,6 +209,34 @@ referencedClasses: []
 }),
 smalltalk.Collection);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "allSatisfy:",
+category: 'enumerating',
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+var $early={};
+try {
+self._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+$1=_st(aBlock)._value_(each);
+if(! smalltalk.assert($1)){
+throw $early=[false];
+};
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
+return true;
+}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"allSatisfy:",{aBlock:aBlock},smalltalk.Collection)})},
+args: ["aBlock"],
+source: "allSatisfy: aBlock\x0a\x09\x22Evaluate aBlock with the elements of the receiver.\x0a\x09If aBlock returns false for any element return false.\x0a\x09Otherwise return true.\x22\x0a\x0a\x09self do: [:each | (aBlock value: each) ifFalse: [^ false]].\x0a\x09^ true",
+messageSends: ["do:", "ifFalse:", "value:"],
+referencedClasses: []
+}),
+smalltalk.Collection);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "anyOne",
@@ -236,6 +264,34 @@ referencedClasses: []
 }),
 smalltalk.Collection);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "anySatisfy:",
+category: 'enumerating',
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+var $early={};
+try {
+self._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+$1=_st(aBlock)._value_(each);
+if(smalltalk.assert($1)){
+throw $early=[true];
+};
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
+return false;
+}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"anySatisfy:",{aBlock:aBlock},smalltalk.Collection)})},
+args: ["aBlock"],
+source: "anySatisfy: aBlock\x0a\x09\x22Evaluate aBlock with the elements of the receiver.\x0a\x09If aBlock returns true for any element return true.\x0a\x09Otherwise return false.\x22\x0a\x0a\x09self do: [:each | (aBlock value: each) ifTrue: [^ true]].\x0a\x09^ false",
+messageSends: ["do:", "ifTrue:", "value:"],
+referencedClasses: []
+}),
+smalltalk.Collection);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "asArray",
@@ -345,22 +401,12 @@ fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-var $early={};
-try {
-self._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
-$1=_st(aBlock)._value_(each);
-if(smalltalk.assert($1)){
-throw $early=[true];
-};
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-return false;
-}
-catch(e) {if(e===$early)return e[0]; throw e}
+$1=self._anySatisfy_(aBlock);
+return $1;
 }, function($ctx1) {$ctx1.fill(self,"contains:",{aBlock:aBlock},smalltalk.Collection)})},
 args: ["aBlock"],
-source: "contains: aBlock\x0a\x09\x22Evaluate aBlock with the elements of the receiver.\x0a\x09If aBlock returns true for any element return true.\x0a\x09Otherwise return false.\x22\x0a\x0a\x09self do: [ :each | (aBlock value: each) ifTrue: [ ^ true ] ].\x0a\x09^ false",
-messageSends: ["do:", "ifTrue:", "value:"],
+source: "contains: aBlock\x0a\x09^ self anySatisfy: aBlock",
+messageSends: ["anySatisfy:"],
 referencedClasses: []
 }),
 smalltalk.Collection);
@@ -721,6 +767,34 @@ referencedClasses: []
 }),
 smalltalk.Collection);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "noneSatisfy:",
+category: 'enumerating',
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+var $early={};
+try {
+self._do_((function(item){
+return smalltalk.withContext(function($ctx2) {
+$1=_st(aBlock)._value_(item);
+if(smalltalk.assert($1)){
+throw $early=[false];
+};
+}, function($ctx2) {$ctx2.fillBlock({item:item},$ctx1,1)})}));
+return true;
+}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"noneSatisfy:",{aBlock:aBlock},smalltalk.Collection)})},
+args: ["aBlock"],
+source: "noneSatisfy: aBlock\x0a\x09\x22Evaluate aBlock with the elements of the receiver.\x0a\x09If aBlock returns false for all elements return true.\x0a\x09Otherwise return false\x22\x0a\x0a\x09self do: [:item | (aBlock value: item) ifTrue: [^ false]].\x0a\x09^ true",
+messageSends: ["do:", "ifTrue:", "value:"],
+referencedClasses: []
+}),
+smalltalk.Collection);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "notEmpty",

+ 97 - 34
js/Kernel-Tests.js

@@ -1356,6 +1356,35 @@ referencedClasses: []
 }),
 smalltalk.CollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testAllSatisfy",
+category: 'tests',
+fn: function (){
+var self=this;
+var collection,anyOne;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+collection=self._collection();
+anyOne=_st(collection)._anyOne();
+$1=_st(collection)._allSatisfy_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(collection)._includes_(each);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
+$ctx1.sendIdx["allSatisfy:"]=1;
+self._assert_($1);
+self._deny_(_st(collection)._allSatisfy_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(each).__tild_eq(anyOne);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,2)})})));
+return self}, function($ctx1) {$ctx1.fill(self,"testAllSatisfy",{collection:collection,anyOne:anyOne},smalltalk.CollectionTest)})},
+args: [],
+source: "testAllSatisfy\x0a\x09| collection anyOne |\x0a\x09collection := self collection.\x0a\x09anyOne := collection anyOne.\x0a\x09self assert: (collection allSatisfy: [ :each | collection includes: each ]).\x0a\x09self deny: (collection allSatisfy: [ :each | each ~= anyOne ])",
+messageSends: ["collection", "anyOne", "assert:", "allSatisfy:", "includes:", "deny:", "~="],
+referencedClasses: []
+}),
+smalltalk.CollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testAnyOne",
@@ -1382,6 +1411,40 @@ referencedClasses: ["Error"]
 }),
 smalltalk.CollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testAnySatisfy",
+category: 'tests',
+fn: function (){
+var self=this;
+var anyOne;
+function $Object(){return smalltalk.Object||(typeof Object=="undefined"?nil:Object)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$3,$2;
+$1=self._collection();
+$ctx1.sendIdx["collection"]=1;
+anyOne=_st($1)._anyOne();
+$3=self._collection();
+$ctx1.sendIdx["collection"]=2;
+$2=_st($3)._anySatisfy_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(each).__eq(anyOne);
+$ctx2.sendIdx["="]=1;
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
+$ctx1.sendIdx["anySatisfy:"]=1;
+self._assert_($2);
+self._deny_(_st(self._collection())._anySatisfy_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(each).__eq(_st($Object())._new());
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,2)})})));
+return self}, function($ctx1) {$ctx1.fill(self,"testAnySatisfy",{anyOne:anyOne},smalltalk.CollectionTest)})},
+args: [],
+source: "testAnySatisfy\x0a\x09| anyOne |\x0a\x09anyOne := self collection anyOne.\x0a\x09self assert: (self collection anySatisfy: [ :each | each = anyOne ]).\x0a\x09self deny: (self collection anySatisfy: [ :each | each = Object new ])",
+messageSends: ["anyOne", "collection", "assert:", "anySatisfy:", "=", "deny:", "new"],
+referencedClasses: ["Object"]
+}),
+smalltalk.CollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testAsArray",
@@ -1464,40 +1527,6 @@ referencedClasses: []
 }),
 smalltalk.CollectionTest);
 
-smalltalk.addMethod(
-smalltalk.method({
-selector: "testContains",
-category: 'tests',
-fn: function (){
-var self=this;
-var anyOne;
-function $Object(){return smalltalk.Object||(typeof Object=="undefined"?nil:Object)}
-return smalltalk.withContext(function($ctx1) { 
-var $1,$3,$2;
-$1=self._collection();
-$ctx1.sendIdx["collection"]=1;
-anyOne=_st($1)._anyOne();
-$3=self._collection();
-$ctx1.sendIdx["collection"]=2;
-$2=_st($3)._contains_((function(each){
-return smalltalk.withContext(function($ctx2) {
-return _st(each).__eq(anyOne);
-$ctx2.sendIdx["="]=1;
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-$ctx1.sendIdx["contains:"]=1;
-self._assert_($2);
-self._deny_(_st(self._collection())._contains_((function(each){
-return smalltalk.withContext(function($ctx2) {
-return _st(each).__eq(_st($Object())._new());
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,2)})})));
-return self}, function($ctx1) {$ctx1.fill(self,"testContains",{anyOne:anyOne},smalltalk.CollectionTest)})},
-args: [],
-source: "testContains\x0a\x09| anyOne |\x0a\x09anyOne := self collection anyOne.\x0a\x09self assert: (self collection contains: [ :each | each = anyOne ]).\x0a\x09self deny: (self collection contains: [ :each | each = Object new ])",
-messageSends: ["anyOne", "collection", "assert:", "contains:", "=", "deny:", "new"],
-referencedClasses: ["Object"]
-}),
-smalltalk.CollectionTest);
-
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testDetect",
@@ -1678,6 +1707,40 @@ referencedClasses: []
 }),
 smalltalk.CollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testNoneSatisfy",
+category: 'tests',
+fn: function (){
+var self=this;
+var anyOne;
+function $Object(){return smalltalk.Object||(typeof Object=="undefined"?nil:Object)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$3,$2;
+$1=self._collection();
+$ctx1.sendIdx["collection"]=1;
+anyOne=_st($1)._anyOne();
+$3=self._collection();
+$ctx1.sendIdx["collection"]=2;
+$2=_st($3)._noneSatisfy_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(each).__eq(anyOne);
+$ctx2.sendIdx["="]=1;
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
+$ctx1.sendIdx["noneSatisfy:"]=1;
+self._deny_($2);
+self._assert_(_st(self._collection())._noneSatisfy_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(each).__eq(_st($Object())._new());
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,2)})})));
+return self}, function($ctx1) {$ctx1.fill(self,"testNoneSatisfy",{anyOne:anyOne},smalltalk.CollectionTest)})},
+args: [],
+source: "testNoneSatisfy\x0a\x09| anyOne |\x0a\x09anyOne := self collection anyOne.\x0a\x09self deny: (self collection noneSatisfy: [ :each | each = anyOne ]).\x0a\x09self assert: (self collection noneSatisfy: [ :each | each = Object new ])",
+messageSends: ["anyOne", "collection", "deny:", "noneSatisfy:", "=", "assert:", "new"],
+referencedClasses: ["Object"]
+}),
+smalltalk.CollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testRemoveAll",

+ 28 - 6
st/Kernel-Collections.st

@@ -149,6 +149,24 @@ copyWithoutAll: aCollection
 
 !Collection methodsFor: 'enumerating'!
 
+allSatisfy: aBlock
+	"Evaluate aBlock with the elements of the receiver.
+	If aBlock returns false for any element return false.
+	Otherwise return true."
+
+	self do: [:each | (aBlock value: each) ifFalse: [^ false]].
+	^ true
+!
+
+anySatisfy: aBlock
+	"Evaluate aBlock with the elements of the receiver.
+	If aBlock returns true for any element return true.
+	Otherwise return false."
+
+	self do: [:each | (aBlock value: each) ifTrue: [^ true]].
+	^ false
+!
+
 collect: aBlock
 	| stream |
 	stream := self class new writeStream.
@@ -201,6 +219,15 @@ intersection: aCollection
 	^ self class withAll: outputSet asArray
 !
 
+noneSatisfy: aBlock
+	"Evaluate aBlock with the elements of the receiver.
+	If aBlock returns false for all elements return true.
+	Otherwise return false"
+
+	self do: [:item | (aBlock value: item) ifTrue: [^ false]].
+	^ true
+!
+
 reject: aBlock
 	^ self select: [ :each | (aBlock value: each) = false ]
 !
@@ -238,12 +265,7 @@ putOn: aStream
 !Collection methodsFor: 'testing'!
 
 contains: aBlock
-	"Evaluate aBlock with the elements of the receiver.
-	If aBlock returns true for any element return true.
-	Otherwise return false."
-
-	self do: [ :each | (aBlock value: each) ifTrue: [ ^ true ] ].
-	^ false
+	^ self anySatisfy: aBlock
 !
 
 ifEmpty: aBlock

+ 22 - 7
st/Kernel-Tests.st

@@ -416,11 +416,26 @@ isCollectionReadOnly
 
 !CollectionTest methodsFor: 'tests'!
 
+testAllSatisfy
+	| collection anyOne |
+	collection := self collection.
+	anyOne := collection anyOne.
+	self assert: (collection allSatisfy: [ :each | collection includes: each ]).
+	self deny: (collection allSatisfy: [ :each | each ~= anyOne ])
+!
+
 testAnyOne
 	self should: [ self collectionClass new anyOne ] raise: Error.
 	self assert: (self collection includes: self collection anyOne)
 !
 
+testAnySatisfy
+	| anyOne |
+	anyOne := self collection anyOne.
+	self assert: (self collection anySatisfy: [ :each | each = anyOne ]).
+	self deny: (self collection anySatisfy: [ :each | each = Object new ])
+!
+
 testAsArray
 	self
 		assertSameContents: self collection
@@ -451,13 +466,6 @@ testCollect
 		as: newCollection
 !
 
-testContains
-	| anyOne |
-	anyOne := self collection anyOne.
-	self assert: (self collection contains: [ :each | each = anyOne ]).
-	self deny: (self collection contains: [ :each | each = Object new ])
-!
-
 testDetect
 	self assert: (self collection detect: [ :each | each < 0 ]) equals: -4.
 	self
@@ -494,6 +502,13 @@ testIsEmpty
 	self deny: self collection isEmpty
 !
 
+testNoneSatisfy
+	| anyOne |
+	anyOne := self collection anyOne.
+	self deny: (self collection noneSatisfy: [ :each | each = anyOne ]).
+	self assert: (self collection noneSatisfy: [ :each | each = Object new ])
+!
+
 testRemoveAll
 	self assert: (self collection removeAll; yourself) equals: self collectionClass new
 !