---
name: "Bag"
section: "3poc"
platform: "linux"
package: "objc-poc"
version: "3.1.26-2"
release: "Debian 3.0 (Woody)"
platforms: ["linux"]
url: "https://new.carta.tech/Bag/3poc"
---

# Bag(3poc)

Portable Object Compiler Bag class

## NAME

Bag - Portable Object Compiler Bag class

## 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.
