Browse Source

Optimize Array >> collect: and #select:

Nicolas Petton 10 years ago
parent
commit
b580d9dccc
3 changed files with 147 additions and 32 deletions
  1. 52 11
      js/Kernel-Collections.deploy.js
  2. 67 16
      js/Kernel-Collections.js
  3. 28 5
      st/Kernel-Collections.st

+ 52 - 11
js/Kernel-Collections.deploy.js

@@ -591,6 +591,28 @@ return $2;
 messageSends: ["writeStream", "new", "class", "do:", "ifTrue:", "nextPut:", "value:", "contents"]}),
 smalltalk.Collection);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "select:thenCollect:",
+fn: function (selectBlock,collectBlock){
+var self=this;
+var stream;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+stream=_st(_st(self._class())._new())._writeStream();
+self._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+$1=_st(selectBlock)._value_(each);
+if(smalltalk.assert($1)){
+return _st(stream)._nextPut_(_st(collectBlock)._value_(each));
+};
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+$2=_st(stream)._contents();
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"select:thenCollect:",{selectBlock:selectBlock,collectBlock:collectBlock,stream:stream},smalltalk.Collection)})},
+messageSends: ["writeStream", "new", "class", "do:", "ifTrue:", "nextPut:", "value:", "contents"]}),
+smalltalk.Collection);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "size",
@@ -1695,17 +1717,6 @@ return $1;
 messageSends: ["at:", "atRandom", "size"]}),
 smalltalk.SequenceableCollection);
 
-smalltalk.addMethod(
-smalltalk.method({
-selector: "collect:",
-fn: function (aBlock){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return self.map(function(each) {return aBlock._value_(each)});
-return self}, function($ctx1) {$ctx1.fill(self,"collect:",{aBlock:aBlock},smalltalk.SequenceableCollection)})},
-messageSends: []}),
-smalltalk.SequenceableCollection);
-
 smalltalk.addMethod(
 smalltalk.method({
 selector: "copyFrom:to:",
@@ -2150,6 +2161,17 @@ return self}, function($ctx1) {$ctx1.fill(self,"at:put:",{anIndex:anIndex,anObje
 messageSends: []}),
 smalltalk.Array);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "collect:",
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self.map(function(each) {return aBlock._value_(each)});
+return self}, function($ctx1) {$ctx1.fill(self,"collect:",{aBlock:aBlock},smalltalk.Array)})},
+messageSends: []}),
+smalltalk.Array);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "join:",
@@ -2233,6 +2255,25 @@ return self}, function($ctx1) {$ctx1.fill(self,"reversed",{},smalltalk.Array)})}
 messageSends: []}),
 smalltalk.Array);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "select:",
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+
+		var result = self.klass._new();
+		for(var i=0; i<self.length; i++) {
+			if(aBlock._value_(self[i])) {
+				result.push(self[i]);
+			}
+		}
+		return result;
+	;
+return self}, function($ctx1) {$ctx1.fill(self,"select:",{aBlock:aBlock},smalltalk.Array)})},
+messageSends: []}),
+smalltalk.Array);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "size",

+ 67 - 16
js/Kernel-Collections.js

@@ -778,6 +778,33 @@ referencedClasses: []
 }),
 smalltalk.Collection);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "select:thenCollect:",
+category: 'enumerating',
+fn: function (selectBlock,collectBlock){
+var self=this;
+var stream;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+stream=_st(_st(self._class())._new())._writeStream();
+self._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+$1=_st(selectBlock)._value_(each);
+if(smalltalk.assert($1)){
+return _st(stream)._nextPut_(_st(collectBlock)._value_(each));
+};
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+$2=_st(stream)._contents();
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"select:thenCollect:",{selectBlock:selectBlock,collectBlock:collectBlock,stream:stream},smalltalk.Collection)})},
+args: ["selectBlock", "collectBlock"],
+source: "select: selectBlock thenCollect: collectBlock\x0a\x09| stream |\x0a\x09stream := self class new writeStream.\x0a\x09self do: [:each |\x0a\x09\x09(selectBlock value: each) ifTrue: [\x0a\x09\x09stream nextPut: (collectBlock value: each)]].\x0a\x09^stream contents",
+messageSends: ["writeStream", "new", "class", "do:", "ifTrue:", "nextPut:", "value:", "contents"],
+referencedClasses: []
+}),
+smalltalk.Collection);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "size",
@@ -2246,22 +2273,6 @@ referencedClasses: []
 }),
 smalltalk.SequenceableCollection);
 
-smalltalk.addMethod(
-smalltalk.method({
-selector: "collect:",
-category: 'enumerating',
-fn: function (aBlock){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return self.map(function(each) {return aBlock._value_(each)});
-return self}, function($ctx1) {$ctx1.fill(self,"collect:",{aBlock:aBlock},smalltalk.SequenceableCollection)})},
-args: ["aBlock"],
-source: "collect: aBlock\x0a\x09\x22Optimized version\x22\x0a\x09<return self.map(function(each) {return aBlock._value_(each)})>",
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.SequenceableCollection);
-
 smalltalk.addMethod(
 smalltalk.method({
 selector: "copyFrom:to:",
@@ -2867,6 +2878,22 @@ referencedClasses: []
 }),
 smalltalk.Array);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "collect:",
+category: 'enumerating',
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self.map(function(each) {return aBlock._value_(each)});
+return self}, function($ctx1) {$ctx1.fill(self,"collect:",{aBlock:aBlock},smalltalk.Array)})},
+args: ["aBlock"],
+source: "collect: aBlock\x0a\x09\x22Optimized version\x22\x0a\x09<return self.map(function(each) {return aBlock._value_(each)})>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Array);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "join:",
@@ -2980,6 +3007,30 @@ referencedClasses: []
 }),
 smalltalk.Array);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "select:",
+category: 'enumerating',
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+
+		var result = self.klass._new();
+		for(var i=0; i<self.length; i++) {
+			if(aBlock._value_(self[i])) {
+				result.push(self[i]);
+			}
+		}
+		return result;
+	;
+return self}, function($ctx1) {$ctx1.fill(self,"select:",{aBlock:aBlock},smalltalk.Array)})},
+args: ["aBlock"],
+source: "select: aBlock\x0a\x09\x22Optimized version\x22\x0a\x09\x0a\x09<\x0a\x09\x09var result = self.klass._new();\x0a\x09\x09for(var i=0; i<self.length; i++) {\x0a\x09\x09\x09if(aBlock._value_(self[i])) {\x0a\x09\x09\x09\x09result.push(self[i]);\x0a\x09\x09\x09}\x0a\x09\x09}\x0a\x09\x09return result;\x0a\x09>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Array);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "size",

+ 28 - 5
st/Kernel-Collections.st

@@ -199,6 +199,15 @@ select: aBlock
 		(aBlock value: each) ifTrue: [
 		stream nextPut: each]].
 	^stream contents
+!
+
+select: selectBlock thenCollect: collectBlock
+	| stream |
+	stream := self class new writeStream.
+	self do: [:each |
+		(selectBlock value: each) ifTrue: [
+		stream nextPut: (collectBlock value: each)]].
+	^stream contents
 ! !
 
 !Collection methodsFor: 'error handling'!
@@ -864,11 +873,6 @@ shallowCopy
 
 !SequenceableCollection methodsFor: 'enumerating'!
 
-collect: aBlock
-	"Optimized version"
-	<return self.map(function(each) {return aBlock._value_(each)})>
-!
-
 detect: aBlock ifNone: anotherBlock
 	<
 		for(var i = 0; i < self.length; i++)
@@ -1011,10 +1015,29 @@ reversed
 
 !Array methodsFor: 'enumerating'!
 
+collect: aBlock
+	"Optimized version"
+	<return self.map(function(each) {return aBlock._value_(each)})>
+!
+
 join: aString
 	<return self.join(aString)>
 !
 
+select: aBlock
+	"Optimized version"
+	
+	<
+		var result = self.klass._new();
+		for(var i=0; i<self.length; i++) {
+			if(aBlock._value_(self[i])) {
+				result.push(self[i]);
+			}
+		}
+		return result;
+	>
+!
+
 sort
 	^self basicPerform: 'sort'
 !