Bladeren bron

IndexableCollection >> indexOf:{,ifAbsent:}

Also removed strange `keyAtValue:` which no one used
and was invalid (detect with two-arg block, reacting on 2nd arg).
Herbert Vojčík 11 jaren geleden
bovenliggende
commit
f054f54dae
6 gewijzigde bestanden met toevoegingen van 1071 en 909 verwijderingen
  1. 63 35
      js/Kernel-Collections.deploy.js
  2. 83 45
      js/Kernel-Collections.js
  3. 458 386
      js/Kernel-Tests.deploy.js
  4. 433 433
      js/Kernel-Tests.js
  5. 23 8
      st/Kernel-Collections.st
  6. 11 2
      st/Kernel-Tests.st

+ 63 - 35
js/Kernel-Collections.deploy.js

@@ -858,6 +858,32 @@ return self}, function($ctx1) {$ctx1.fill(self,"at:put:",{anIndex:anIndex,anObje
 messageSends: ["subclassReponsibility"]}),
 smalltalk.IndexableCollection);
 
+smalltalk.addMethod(
+"_indexOf_",
+smalltalk.method({
+selector: "indexOf:",
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self)._indexOf_ifAbsent_(anObject,(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._errorNotFound();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"indexOf:",{anObject:anObject}, smalltalk.IndexableCollection)})},
+messageSends: ["indexOf:ifAbsent:", "errorNotFound"]}),
+smalltalk.IndexableCollection);
+
+smalltalk.addMethod(
+"_indexOf_ifAbsent_",
+smalltalk.method({
+selector: "indexOf:ifAbsent:",
+fn: function (anObject,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._subclassResponsibility();
+return self}, function($ctx1) {$ctx1.fill(self,"indexOf:ifAbsent:",{anObject:anObject,aBlock:aBlock}, smalltalk.IndexableCollection)})},
+messageSends: ["subclassResponsibility"]}),
+smalltalk.IndexableCollection);
+
 smalltalk.addMethod(
 "_with_do_",
 smalltalk.method({
@@ -1174,6 +1200,21 @@ return self}, function($ctx1) {$ctx1.fill(self,"includesKey:",{aKey:aKey}, small
 messageSends: []}),
 smalltalk.HashedCollection);
 
+smalltalk.addMethod(
+"_indexOf_ifAbsent_",
+smalltalk.method({
+selector: "indexOf:ifAbsent:",
+fn: function (anObject,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._keys())._detect_ifNone_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(self)._at_(each)).__eq(anObject);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),aBlock);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"indexOf:ifAbsent:",{anObject:anObject,aBlock:aBlock}, smalltalk.HashedCollection)})},
+messageSends: ["detect:ifNone:", "=", "at:", "keys"]}),
+smalltalk.HashedCollection);
+
 smalltalk.addMethod(
 "_keys",
 smalltalk.method({
@@ -1512,6 +1553,28 @@ return self}, function($ctx1) {$ctx1.fill(self,"includesKey:",{aKey:aKey}, small
 messageSends: []}),
 smalltalk.Dictionary);
 
+smalltalk.addMethod(
+"_indexOf_ifAbsent_",
+smalltalk.method({
+selector: "indexOf:ifAbsent:",
+fn: function (anObject,aBlock){
+var self=this;
+var index;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+index=_st(self["@values"])._indexOf_ifAbsent_(anObject,(function(){
+return smalltalk.withContext(function($ctx2) {
return (0);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$2=_st(index).__eq((0));
+if(smalltalk.assert($2)){
+$1=_st(aBlock)._value();
+} else {
+$1=_st(self["@keys"])._at_(index);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"indexOf:ifAbsent:",{anObject:anObject,aBlock:aBlock,index:index}, smalltalk.Dictionary)})},
+messageSends: ["indexOf:ifAbsent:", "ifTrue:ifFalse:", "value", "at:", "="]}),
+smalltalk.Dictionary);
+
 smalltalk.addMethod(
 "_initialize",
 smalltalk.method({
@@ -1526,26 +1589,6 @@ return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.Dictio
 messageSends: ["initialize"]}),
 smalltalk.Dictionary);
 
-smalltalk.addMethod(
-"_keyAtValue_",
-smalltalk.method({
-selector: "keyAtValue:",
-fn: function (anObject){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(_st(_st(self)._associations())._detect_ifNone_((function(k,v){
-return smalltalk.withContext(function($ctx2) {
-return _st(v).__eq_eq(anObject);
-}, function($ctx2) {$ctx2.fillBlock({k:k,v:v},$ctx1)})}),(function(){
-return smalltalk.withContext(function($ctx2) {
-return _st(self)._error_("Not found");
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._key();
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"keyAtValue:",{anObject:anObject}, smalltalk.Dictionary)})},
-messageSends: ["key", "detect:ifNone:", "==", "error:", "associations"]}),
-smalltalk.Dictionary);
-
 smalltalk.addMethod(
 "_keys",
 smalltalk.method({
@@ -1856,21 +1899,6 @@ return $1;
 messageSends: ["notNil", "indexOf:ifAbsent:"]}),
 smalltalk.SequenceableCollection);
 
-smalltalk.addMethod(
-"_indexOf_",
-smalltalk.method({
-selector: "indexOf:",
-fn: function (anObject){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=_st(self)._indexOf_ifAbsent_(anObject,(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(self)._errorNotFound();
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"indexOf:",{anObject:anObject}, smalltalk.SequenceableCollection)})},
-messageSends: ["indexOf:ifAbsent:", "errorNotFound"]}),
-smalltalk.SequenceableCollection);
-
 smalltalk.addMethod(
 "_indexOf_ifAbsent_",
 smalltalk.method({

+ 83 - 45
js/Kernel-Collections.js

@@ -1124,6 +1124,42 @@ referencedClasses: []
 }),
 smalltalk.IndexableCollection);
 
+smalltalk.addMethod(
+"_indexOf_",
+smalltalk.method({
+selector: "indexOf:",
+category: 'accessing',
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self)._indexOf_ifAbsent_(anObject,(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._errorNotFound();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"indexOf:",{anObject:anObject}, smalltalk.IndexableCollection)})},
+args: ["anObject"],
+source: "indexOf: anObject\x0a\x09\x22Lookup index at which anObject is stored in the receiver.\x0a\x09If not present, raise an error.\x22\x0a\x0a\x09^self indexOf: anObject ifAbsent: [ self errorNotFound ]",
+messageSends: ["indexOf:ifAbsent:", "errorNotFound"],
+referencedClasses: []
+}),
+smalltalk.IndexableCollection);
+
+smalltalk.addMethod(
+"_indexOf_ifAbsent_",
+smalltalk.method({
+selector: "indexOf:ifAbsent:",
+category: 'accessing',
+fn: function (anObject,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._subclassResponsibility();
+return self}, function($ctx1) {$ctx1.fill(self,"indexOf:ifAbsent:",{anObject:anObject,aBlock:aBlock}, smalltalk.IndexableCollection)})},
+args: ["anObject", "aBlock"],
+source: "indexOf: anObject ifAbsent: aBlock\x0a\x09\x22Lookup index at which anObject is stored in the receiver.\x0a\x09If not present, return value of executing aBlock.\x22\x0a\x0a\x09self subclassResponsibility",
+messageSends: ["subclassResponsibility"],
+referencedClasses: []
+}),
+smalltalk.IndexableCollection);
+
 smalltalk.addMethod(
 "_with_do_",
 smalltalk.method({
@@ -1541,6 +1577,26 @@ referencedClasses: []
 }),
 smalltalk.HashedCollection);
 
+smalltalk.addMethod(
+"_indexOf_ifAbsent_",
+smalltalk.method({
+selector: "indexOf:ifAbsent:",
+category: 'accessing',
+fn: function (anObject,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._keys())._detect_ifNone_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(self)._at_(each)).__eq(anObject);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),aBlock);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"indexOf:ifAbsent:",{anObject:anObject,aBlock:aBlock}, smalltalk.HashedCollection)})},
+args: ["anObject", "aBlock"],
+source: "indexOf: anObject ifAbsent: aBlock\x0a\x0a\x09^ self keys detect: [ :each | (self at: each) = anObject ] ifNone: aBlock",
+messageSends: ["detect:ifNone:", "=", "at:", "keys"],
+referencedClasses: []
+}),
+smalltalk.HashedCollection);
+
 smalltalk.addMethod(
 "_keys",
 smalltalk.method({
@@ -1979,6 +2035,33 @@ referencedClasses: []
 }),
 smalltalk.Dictionary);
 
+smalltalk.addMethod(
+"_indexOf_ifAbsent_",
+smalltalk.method({
+selector: "indexOf:ifAbsent:",
+category: 'accessing',
+fn: function (anObject,aBlock){
+var self=this;
+var index;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+index=_st(self["@values"])._indexOf_ifAbsent_(anObject,(function(){
+return smalltalk.withContext(function($ctx2) {
return (0);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$2=_st(index).__eq((0));
+if(smalltalk.assert($2)){
+$1=_st(aBlock)._value();
+} else {
+$1=_st(self["@keys"])._at_(index);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"indexOf:ifAbsent:",{anObject:anObject,aBlock:aBlock,index:index}, smalltalk.Dictionary)})},
+args: ["anObject", "aBlock"],
+source: "indexOf: anObject ifAbsent: aBlock\x0a\x0a\x09| index |\x0a    index := values indexOf: anObject ifAbsent: [0].\x0a    ^ index = 0 ifTrue: [ aBlock value ] ifFalse: [ keys at: index ]",
+messageSends: ["indexOf:ifAbsent:", "ifTrue:ifFalse:", "value", "at:", "="],
+referencedClasses: []
+}),
+smalltalk.Dictionary);
+
 smalltalk.addMethod(
 "_initialize",
 smalltalk.method({
@@ -1998,31 +2081,6 @@ referencedClasses: []
 }),
 smalltalk.Dictionary);
 
-smalltalk.addMethod(
-"_keyAtValue_",
-smalltalk.method({
-selector: "keyAtValue:",
-category: 'accessing',
-fn: function (anObject){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(_st(_st(self)._associations())._detect_ifNone_((function(k,v){
-return smalltalk.withContext(function($ctx2) {
-return _st(v).__eq_eq(anObject);
-}, function($ctx2) {$ctx2.fillBlock({k:k,v:v},$ctx1)})}),(function(){
-return smalltalk.withContext(function($ctx2) {
-return _st(self)._error_("Not found");
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._key();
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"keyAtValue:",{anObject:anObject}, smalltalk.Dictionary)})},
-args: ["anObject"],
-source: "keyAtValue: anObject\x0a\x0a\x09^ (self associations \x0a    \x09detect:[:k :v| v == anObject] \x0a    \x09ifNone:[self error: 'Not found']) key",
-messageSends: ["key", "detect:ifNone:", "==", "error:", "associations"],
-referencedClasses: []
-}),
-smalltalk.Dictionary);
-
 smalltalk.addMethod(
 "_keys",
 smalltalk.method({
@@ -2434,26 +2492,6 @@ referencedClasses: []
 }),
 smalltalk.SequenceableCollection);
 
-smalltalk.addMethod(
-"_indexOf_",
-smalltalk.method({
-selector: "indexOf:",
-category: 'accessing',
-fn: function (anObject){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=_st(self)._indexOf_ifAbsent_(anObject,(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(self)._errorNotFound();
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"indexOf:",{anObject:anObject}, smalltalk.SequenceableCollection)})},
-args: ["anObject"],
-source: "indexOf: anObject\x0a\x09^self indexOf: anObject ifAbsent: [self errorNotFound]",
-messageSends: ["indexOf:ifAbsent:", "errorNotFound"],
-referencedClasses: []
-}),
-smalltalk.SequenceableCollection);
-
 smalltalk.addMethod(
 "_indexOf_ifAbsent_",
 smalltalk.method({

File diff suppressed because it is too large
+ 458 - 386
js/Kernel-Tests.deploy.js


File diff suppressed because it is too large
+ 433 - 433
js/Kernel-Tests.js


+ 23 - 8
st/Kernel-Collections.st

@@ -350,6 +350,20 @@ at: anIndex put: anObject
 	"Store anObject under the given index in the receiver."
 
 	self subclassReponsibility
+!
+
+indexOf: anObject
+	"Lookup index at which anObject is stored in the receiver.
+	If not present, raise an error."
+
+	^self indexOf: anObject ifAbsent: [ self errorNotFound ]
+!
+
+indexOf: anObject ifAbsent: aBlock
+	"Lookup index at which anObject is stored in the receiver.
+	If not present, return value of executing aBlock."
+
+	self subclassResponsibility
 ! !
 
 !IndexableCollection methodsFor: 'enumeration'!
@@ -410,6 +424,11 @@ at: aKey put: aValue
 	^self basicAt: aKey put: aValue
 !
 
+indexOf: anObject ifAbsent: aBlock
+
+	^ self keys detect: [ :each | (self at: each) = anObject ] ifNone: aBlock
+!
+
 keys
 	<
 		if ('function'===typeof Object.keys) return Object.keys(self);
@@ -613,11 +632,11 @@ at: aKey put: aValue
 	>
 !
 
-keyAtValue: anObject
+indexOf: anObject ifAbsent: aBlock
 
-	^ (self associations 
-    	detect:[:k :v| v == anObject] 
-    	ifNone:[self error: 'Not found']) key
+	| index |
+    index := values indexOf: anObject ifAbsent: [0].
+    ^ index = 0 ifTrue: [ aBlock value ] ifFalse: [ keys at: index ]
 !
 
 keys
@@ -733,10 +752,6 @@ fourth
 	^self at: 4
 !
 
-indexOf: anObject
-	^self indexOf: anObject ifAbsent: [self errorNotFound]
-!
-
 indexOf: anObject ifAbsent: aBlock
 	<
 		for(var i=0;i<self.length;i++) {

+ 11 - 2
st/Kernel-Tests.st

@@ -428,11 +428,20 @@ CollectionTest subclass: #HashedCollectionTest
 !HashedCollectionTest methodsFor: 'accessing'!
 
 collection
-	^ #{ 'a' -> 1. 'b' -> 2. 'c' -> 3. 'd' -> -4 }
+	^ #{ 'b' -> 1. 'a' -> 2. 'c' -> 3. 'd' -> -4 }
 !
 
 collectionWithDuplicates
-	^ #{ 'a' -> 1. 'b' -> 2. 'c' -> 3. 'd' -> -4. 'e' -> 1. 'f' -> 2. 'g' -> 10 }
+	^ #{ 'b' -> 1. 'a' -> 2. 'c' -> 3. 'd' -> -4. 'e' -> 1. 'f' -> 2. 'g' -> 10 }
+! !
+
+!HashedCollectionTest methodsFor: 'tests'!
+
+testIndexOf
+
+	self assert: (self collection indexOf: 2) equals: 'a'.
+	self should: [ self collection indexOf: 999 ] raise: Error.
+	self assert: (self collection indexOf: 999 ifAbsent: [ 'sentinel' ]) equals: 'sentinel'
 ! !
 
 !HashedCollectionTest class methodsFor: 'accessing'!

Some files were not shown because too many files changed in this diff