# bag Specification Sheet

Portable Object Compiler (c) 1997,98. All Rights Reserved.

# Bag

Inherits from: Cltn

## Class Description

Bag instances are unordered sets of objects, with possibly duplicate elements. A Bag can be thought of, as a Set, assigning to each element, a count of how many times that element was added (multiplicity of the element).

The multiplicity of a particular element is returned by the occurrencesOf: message. Repeatedly adding the same (in the sense of hash and isEqual) object, simply increases the multiplicity of the element. Sending remove: messages, will not remove the element until the multiplicity of the element is zero.

## Adding Objects

The methods add:, addNTest:, filter:, replace: and add:ifDuplicate: are used to add objects to a Bag. The difference between these methods is the procedure used in adding, how duplicates are handled and what value is returned.

## Difference with OrdCltn

Users should realize that, unlike OrdCltn, Bag does not preserve pointer equality (equality in the isSame sense). Bag's instance method eachElement will return a sequence of objects, possibly containing duplicate elements, but those so-called duplicates will simply be pointers to the same element. Also, since Bag is unordered, the order in which elements will be returned, is not the same as the order in which they were added.

## Method types

### Creation

- new
- new:
- with:
- with:with:
- add:
- copy
- deepCopy
- emptyYourself
- freeContents
- free

### Interrogation

- size
- isEmpty
- eachElement

### Comparing

- isEqual:

### Adding

- add:
- addNTest:
- filter:
- add:ifDuplicate:
- replace:

### Removing

- remove:
- remove:ifAbsent:

### Testing Contents

- includesAllOf:
- includesAnyOf:

### Adding and Removing Contents

- addAll:
- addContentsOf:
- addContentsTo:
- removeAll:
- removeContentsFrom:
- removeContentsOf:

### Combining

- intersection:
- union:
- difference:

### Converting

- asSet
- asOrdCltn

### Using Blocks

- detect:
- detect:ifNone:
- select:
- reject:
- collect:
- count:

### Making elements perform

- elementsPerform:
- elementsPerform:with:
- elementsPerform:with:with:
- elementsPerform:with:with:with:

### Do Blocks

- do:
- do:until:

### Locating

- find:
- contains:
- includes:
- occurrencesOf:

### Printing

- printOn:

### Archiving

- fileOutOn:
- fileInFrom:
- awakeFrom:

## Methods

### new

> +new

Returns a new empty Bag.

### new:

> +new:(unsigned)n

Returns a new empty Bag, which can hold at least n different elements.

### copy

> -copy

Returns a new copy of the Bag.

### deepCopy

> -deepCopy

Returns a new copy of the Bag. The elements in the new Bag are deep copies of the elements in the original Bag.

### emptyYourself

> -emptyYourself

Empties all the members of the Bag (without freeing them). Returns the receiver.

### freeContents

> -freeContents

Removes and frees all the members of the Bag, but doesn't free the Bag itself. Returns the receiver.

### free

> -free

Frees the Bag, but not its elements. Returns nil. Do :

>     bag = [[bag freeContents] free];

if you want to free the Bag and its contents.

### size

> - (unsigned)size

Returns the number of elements in the Bag.

If an Object was added twice, then size returns two, not one, although that the Bag internally stores only one occurence of the Object.

### isEmpty

> - (BOOL)isEmpty

Whether the number of objects in the Bag is equal to zero.

### eachElement

> -eachElement

Returns a sequence of elements in the Bag. If the multiplicity of an object in the Bag is greater than one, pointers to the same object will occur multiple times in the Sequence.

>     aSeq = [aBag eachElement];
>     while ((anElement = [aSeq next])) {
>         /* do something */
>     }
>     aSeq = [aSeq free];

### isEqual:

> - (BOOL)isEqual:bag

Returns YES if bag is a Bag, if bag has the same number of elements as the receiver, and if each member of the contents of bag is contained in the receiver's contents.

### add:

> -add:anObject

Adds anObject to the Bag, and, if it's a duplicate, simply increases the multiplicity of the element. This method doesn't inform the caller about whether the Object was a duplicate, because the receiver is always returned.

### addNTest:

> -addNTest:anObject

Adds anObject if it was not previously in the Bag, otherwise increases the multiplicity of the matching element. Returns anObject if it was not a duplicate, otherwise returns nil, but in either case adds the object to the Bag.

### filter:

> -filter:anObject

The filter: method has a special purpose. If there is a matching object in the Bag, then anObject is freed, the multiplicity of the matching element is increased, and the matching object is returned. Otherwise, anObject is added and returned.

### add:ifDuplicate:

> -add:anObject ifDuplicate:aBlock

Adds and returns anObject, if there was no duplicate previously in the Bag.

Otherwise, this method evalutes aBlock and returns the matching object (the object that was already in the Bag).

For example, the filter: method is equivalent to :

>     [ Bag add: anObject ifDuplicate: { [anObject free] }];

### replace:

> -replace:anObject

If a matching object is found, then anObject replaces that object, and the matching object is returned. If there is no matching object, anObject is added to the receiver, and nil is returned.

### remove:

> -remove:oldObject

Removes oldObject or the element which matches it using isEqual:. Returns the removed entry, or nil if there is no matching entry.

Note: The remove: method of the OrdCltn class is implemented to remove an exact match. The Set class uses a match in the sense of isEqual: instead.

### remove:ifAbsent:

> -remove:oldObject ifAbsent:exceptionBlock

Removes oldObject or the element which matches it using isEqual:. Returns the removed entry, or return value of exceptionBlock if there is no matching entry.

For example, the method remove: is equivalent to :

>     [ aBag remove: oldObject ifAbsent: { nil } ];

Note: The remove: method of the OrdCltn class is implemented to remove an exact match. The Set class uses a match in the sense of isEqual: instead.

### find:

> -find:anObject

Returns any element in the receiver which isEqual: to anObject. Otherwise, returns nil.

### contains:

> - (BOOL)contains:anObject

Returns YES if the receiver contains anObject. Otherwise, returns NO. Implementation is in terms of the receiver's find: method (which uses isEqual: and hash to decide whether the object is contained in the Bag).

### includes:

> - (BOOL)includes:anObject

This method is equivalent to contains:.

### occurrencesOf:

> - (unsigned)occurrencesOf:anObject

Returns the multiplicity of anObject in the receiver, i.e. the number of Objects that are equal (in the sense of isEqual to anObject), otherwise returns 0.

### printOn:

> -printOn:(IOD)aFile

Prints a list of the objects in the Bag by sending each individual object a printOn: message. Returns the receiver.

### fileOutOn:

> -fileOutOn:aFiler

Writes out non-nil objects in the Set on aFiler. Returns the receiver.

### fileInFrom:

> -fileInFrom:aFiler

Reads in objects from aFiler. Returns the receiver, which is a Bag that is not yet usable (until the Bag gets the awakeFrom: message).

### awakeFrom:

> -awakeFrom:aFiler

Rehashes the contents of the Bag, which was previously read from aFiler by the fileInFrom: method. The hash-values of the objects are possibly process or architecture dependent, so they are not stored on the filer. Rather, awakeFrom: recomputes the values.