Docs Menu
Docs Home
/ /
Atlas Device SDKs
/ / /

Sets - React Native SDK

On this page

  • Realm Object Models
  • Create an Object With a Set
  • Add Items to a Set
  • Check if a Set has Specific Items and Check the Size of a Set
  • Remove Set Information
  • Traverse a Set

New in version realm@10.5.0.

A Realm Set is a special object that allows you to store a collection of unique values. Realm Sets are based on JavaScript sets, but can only contain values of a single type and can only be modified within a write transaction. Sets allow you to perform math operations such as finding the union, intersection, or difference between two Sets. To learn more about performing these operations, see the MDN docs for Implementing basic set operations.

You can define a Realm object model property type as a Realm Set, in a two ways:

  • Specify the data type the Set will contain, followed by <>.

  • Use object notation and the type field for more complicated properties.

1class Character extends Realm.Object {
2 static schema = {
3 name: 'Character',
4 primaryKey: '_id',
5 properties: {
6 _id: 'objectId',
7 name: 'string',
8 levelsCompleted: 'int<>',
9 inventory: {
10 type: 'set',
11 objectType: 'string',
12 },
13 },
14 };
15}
1class Character extends Realm.Object<Character> {
2 _id!: Realm.BSON.ObjectId;
3 name!: string;
4 levelsCompleted!: Realm.Set<number>;
5 inventory!: Realm.Set<string>;
6
7 static schema: ObjectSchema = {
8 name: 'Character',
9 primaryKey: '_id',
10 properties: {
11 _id: 'objectId',
12 name: 'string',
13 levelsCompleted: 'int<>',
14 inventory: {
15 type: 'set',
16 objectType: 'string',
17 },
18 },
19 };
20}

To create an object with a Realm Set property, you must create the object within a write transaction. When defining your Realm object, initialize the Realm Set by passing an empty array or an array with your initial values.

In the following example of a CreateInitialCharacters component, we create Character objects with Set properties.

The CreateInitialCharacters component does the following:

  • Gets access to an opened realm instance by calling the useRealm() hook within the component.

  • Uses React's useEffect hook to call an anonymous function only once with useEffect and an empty dependency array. Within the anonymous function, we create two different Character objects within a write transaction. We set each character's inventory and levelsCompleted sets as an array with initial values.

  • Retrieves all characters in the realm instance by passing the Character class to the useQuery() hook.

  • Displays each character's name in the UI as a Text element.

1const CreateInitialCharacters = () => {
2 const realm = useRealm();
3 useEffect(() => {
4 realm.write(() => {
5 realm.create('Character', {
6 _id: new Realm.BSON.ObjectId(),
7 name: 'AdventurousPlayer',
8 inventory: ['elixir', 'compass', 'glowing shield'],
9 levelsCompleted: [4, 9],
10 });
11 });
12 realm.write(() => {
13 realm.create('Character', {
14 _id: new Realm.BSON.ObjectId(),
15 name: 'HealerPlayer',
16 inventory: ['estus flask', 'gloves', 'rune'],
17 levelsCompleted: [1, 2, 5, 24],
18 });
19 });
20 }, []);
21 const characters = useQuery(Character);
22
23 return (
24 <View>
25 {characters.map(character => (
26 <View key={character._id}>
27 <Text>{character.name}</Text>
28 </View>
29 ))}
30 </View>
31 );
32};
1const CreateInitialCharacters = () => {
2 const realm = useRealm();
3 useEffect(() => {
4 realm.write(() => {
5 realm.create('Character', {
6 _id: new Realm.BSON.ObjectId(),
7 name: 'AdventurousPlayer',
8 inventory: ['elixir', 'compass', 'glowing shield'],
9 levelsCompleted: [4, 9],
10 });
11 });
12
13 realm.write(() => {
14 realm.create('Character', {
15 _id: new Realm.BSON.ObjectId(),
16 name: 'HealerPlayer',
17 inventory: ['estus flask', 'gloves', 'rune'],
18 levelsCompleted: [1, 2, 5, 24],
19 });
20 });
21 }, []);
22 const characters = useQuery(Character);
23
24 return (
25 <View>
26 {characters.map(character => (
27 <View key={character._id}>
28 <Text>{character.name}</Text>
29 </View>
30 ))}
31 </View>
32 );
33};

To add an item to a Set, pass the new value to the Realm.Set.add() method method within a write transaction.

In the following example of a AddInventoryToCharacter component, we add new Set elements to the character's inventory.

The AddInventoryToCharacter component does the following:

  • Gets access to an opened realm instance by calling the useRealm() hook within the component.

  • Creates a state variable called "inventoryItem" that represents the new inventory item to add to the inventory Set.

  • Retrieves the character by passing the Character class to the useQuery() hook and running the Collection.filtered() method on the result to filter for characters with the name matching the characterName prop. Then we set the variable character to the first matching result.

  • Creates a component method addInventoryItem() that performs a write transaction that adds an inventory item to the character's inventory by passing the inventoryItem state variable to Realm.Set.add().

  • Renders a TextInput that changes the inventoryItem state variable, and a Button that calls the addInventoryItem() method.

1const AddInventoryToCharacter = ({characterName}) => {
2 const realm = useRealm();
3 const [inventoryItem, setInventoryItem] = useState('');
4 const character = useQuery(
5 Character,
6 characters => {
7 return characters.filtered(`name = '${characterName}'`);
8 },
9 [characterName],
10 )[0];
11
12 const addInventoryItem = () => {
13 realm.write(() => {
14 character?.inventory.add(inventoryItem);
15 });
16 };
17
18 return (
19 <View>
20 <TextInput
21 onChangeText={text => setInventoryItem(text)}
22 value={inventoryItem}
23 />
24 <Button
25 title='Add Inventory Item'
26 onPress={addInventoryItem}
27 />
28 </View>
29 );
30};
1const AddInventoryToCharacter = ({
2 characterName,
3}: {
4 characterName: string;
5}) => {
6 const realm = useRealm();
7 const [inventoryItem, setInventoryItem] = useState('');
8 const character = useQuery(
9 Character,
10 characters => {
11 return characters.filtered(`name = '${characterName}'`);
12 },
13 [characterName],
14 )[0];
15
16 const addInventoryItem = () => {
17 realm.write(() => {
18 character?.inventory.add(inventoryItem);
19 });
20 };
21
22 return (
23 <View>
24 <TextInput
25 onChangeText={text => setInventoryItem(text)}
26 value={inventoryItem}
27 />
28 <Button
29 title='Add Inventory Item'
30 onPress={addInventoryItem}
31 />
32 </View>
33 );
34};

You may want to check for information about your Set, such as its size or if it contains specific item.

To determine if a Set contains a particular value, pass the value to the Realm.Set.has() method. This method will return true if the Set contains the value specified.

To discover how many items are in a Set, you can check its size property.

In the following example of a QueryCharacterInventory component, we check the character's inventory size and if it has a specific item.

The QueryCharacterInventory component does the following:

  • Creates a state variable called "inventoryItem" that represents the inventory item that you want to search the character's inventory for.

  • Uses the useQuery hook to perform a query for all characters, and filter the results to only include the characters with the name matching the characterName passed to the component as a prop. Then we get the first matching result.

  • Retrieves the character by passing the Character class to the useQuery() hook and running the Collection.filtered() method on the result to filter for characters with the name matching the characterName prop. Then we set the variable character to the first matching result.

  • Creates a component method queryCharacterInventory that passes the inventoryItem state variable to Realm.Set.has() to check if the character's inventory contains the item. If the character's inventory contains the item, the method alerts that the character has the item. If the character's inventory does not contain the item, the method alerts that the character does not have the item.

  • Renders the character's name, and renders the inventory size using the size property of the character's inventory. It also renders a TextInput that changes the inventoryItem state variable, and a Button that calls the queryCharacterInventory method.

1const QueryCharacterInventory = ({characterName}) => {
2 const [inventoryItem, setInventoryItem] = useState('');
3 const character = useQuery(
4 Character,
5 characters => {
6 return characters.filtered(`name = '${characterName}'`);
7 },
8 [characterName],
9 )[0];
10
11 const queryCharacterInventory = () => {
12 const characterDoesHaveItem = character.inventory.has(inventoryItem);
13 if (characterDoesHaveItem) {
14 Alert.alert(`Character has item: ${inventoryItem}`);
15 } else {
16 Alert.alert(`Item not found in character's inventory`);
17 }
18 };
19 return (
20 <View>
21 <Text>{character.name}</Text>
22 <Text>
23 Total number of inventory items: {character.inventory.size}
24 </Text>
25 <TextInput
26 onChangeText={text => setInventoryItem(text)}
27 value={inventoryItem}
28 />
29 <Button
30 title='Query for Inventory'
31 onPress={queryCharacterInventory}
32 />
33 </View>
34 );
35};
1const QueryCharacterInventory = ({
2 characterName,
3}: {
4 characterName: string;
5}) => {
6 const [inventoryItem, setInventoryItem] = useState('');
7 const character = useQuery(
8 Character,
9 characters => {
10 return characters.filtered(`name = '${characterName}'`);
11 },
12 [characterName],
13 )[0];
14
15 const queryCharacterInventory = () => {
16 const characterDoesHaveItem: Boolean =
17 character.inventory.has(inventoryItem);
18 if (characterDoesHaveItem) {
19 Alert.alert(`Character has item: ${inventoryItem}`);
20 } else {
21 Alert.alert(`Item not found in character's inventory`);
22 }
23 };
24 return (
25 <View>
26 <Text>{character.name}</Text>
27 <Text>
28 Total number of inventory items: {character.inventory.size}
29 </Text>
30 <TextInput
31 onChangeText={text => setInventoryItem(text)}
32 value={inventoryItem}
33 />
34 <Button
35 title='Query for Inventory'
36 onPress={queryCharacterInventory}
37 />
38 </View>
39 );
40};

You may want to remove a specific item or all items from a Set.

To remove a specific value from a Set, pass the value to the Realm.Set.delete() method within a write transaction.

To clear the Set, run the Realm.Set.clear() method within a write transaction.

In the following example of a RemoveInventoryFromCharacter component, we remove a specific item from the Set and clear the Set of all items.

The RemoveInventoryFromCharacter component does the following:

  • Gets access to an opened realm instance by calling the useRealm() hook within the component.

  • Creates a state variable called "inventoryItem" that represents the inventory item to remove from the inventory Set.

  • Creates a component method removeInventoryItem that passes the inventoryItem state variable to Realm.Set.delete() to remove the item from the character's inventory.

  • Creates a component method removeAllInventory that calls Realm.Set.clear() to remove all items from the character's inventory.

  • Renders a TextInput that changes the inventoryItem state variable, and two Button components that call the removeInventoryItem and removeAllInventory methods, respectively.

1const RemoveInventoryFromCharacter = ({characterName}) => {
2 const realm = useRealm();
3 const [inventoryItem, setInventoryItem] = useState('');
4 const character = useQuery(
5 Character,
6 characters => {
7 return characters.filtered(`name = '${characterName}'`);
8 },
9 [characterName],
10 )[0];
11
12 const removeInventoryItem = () => {
13 realm.write(() => {
14 character?.inventory.delete(inventoryItem);
15 });
16 };
17 const removeAllInventory = () => {
18 realm.write(() => {
19 character?.inventory.clear();
20 });
21 };
22 return (
23 <View>
24 <Text>{character.name}</Text>
25 <TextInput
26 onChangeText={text => setInventoryItem(text)}
27 value={inventoryItem}
28 />
29 <Button
30 title='Remove Inventory Item'
31 onPress={removeInventoryItem}
32 />
33 <Button
34 title='Remove All Inventory'
35 onPress={removeAllInventory}
36 />
37 </View>
38 );
39};
1const RemoveInventoryFromCharacter = ({
2 characterName,
3}: {
4 characterName: string;
5}) => {
6 const realm = useRealm();
7 const [inventoryItem, setInventoryItem] = useState('');
8 const character = useQuery(
9 Character,
10 characters => {
11 return characters.filtered(`name = '${characterName}'`);
12 },
13 [characterName],
14 )[0];
15
16 const removeInventoryItem = () => {
17 realm.write(() => {
18 character?.inventory.delete(inventoryItem);
19 });
20 };
21 const removeAllInventory = () => {
22 realm.write(() => {
23 character?.inventory.clear();
24 });
25 };
26 return (
27 <View>
28 <Text>{character.name}</Text>
29 <TextInput
30 onChangeText={text => setInventoryItem(text)}
31 value={inventoryItem}
32 />
33 <Button
34 title='Remove Inventory Item'
35 onPress={removeInventoryItem}
36 />
37 <Button
38 title='Remove All Inventory'
39 onPress={removeAllInventory}
40 />
41 </View>
42 );
43};

You can traverse a Set to access each item in the Set. To traverse a Set, use the Set.map() method or alternative iteration method.

However, by default the order of the items in a Set is not guaranteed. To traverse a Set in order, you can store the Set's items in a state variable and update that state variable when you add new items to the Set.

In the following example of a TraverseCharacterInventory component, a character starts with no inventory items. When the user adds items to the inventory Set, the component displays each item in the Set in both an ordered and unordered list.

The TraverseCharacterInventory component does the following:

  • Gets access to an opened realm instance by calling the useRealm() hook within the component.

  • Creates a state variable called "inventoryItem" that represents the new inventory item to add to the inventory Set.

  • Creates a state variable called "inventory" that will hold the character's inventory items in order of insertion.

  • Retrieves the character by passing the Character class to the useQuery() hook and running the Collection.filtered() method on the result to filter for characters with the name matching the characterName prop. Then we set the variable character to the first matching result.

  • Creates a component method addInventoryItem() that performs a write transaction that adds an inventory item to the character's inventory by passing the inventoryItem state variable to the Realm.Set.add() method. After the write transaction, the method adds the inventoryItem to the inventory array state variable.

  • Renders a TextInput that changes the inventoryItem state variable, and a Button that calls the addInventoryItem() method.

  • Renders a list of the character's inventory items in the order they were added to the Set by iterating through the inventory array state variable.

  • Renders a unordered list of the character's inventory by iterating through character.inventory.

1const TraverseCharacterInventory = ({characterName}) => {
2 const realm = useRealm();
3 const [inventoryItem, setInventoryItem] = useState('');
4 const [inventory, setInventory] = useState([]);
5
6 const character = useQuery(
7 Character,
8 characters => {
9 return characters.filtered(`name = '${characterName}'`);
10 },
11 [characterName],
12 )[0];
13
14 const addInventoryItem = () => {
15 realm.write(() => {
16 character?.inventory.add(inventoryItem);
17 });
18 setInventory([...inventory, inventoryItem]);
19 };
20
21 return (
22 <View>
23 <Text>{character.name}</Text>
24 <Text>Add an item to the inventory:</Text>
25 <TextInput
26 onChangeText={text => setInventoryItem(text)}
27 value={inventoryItem}
28 />
29 <Button
30 title='Add Inventory Item'
31 onPress={addInventoryItem}
32 />
33
34 <Text>Ordered Inventory:</Text>
35 {inventory.map(item => (
36 <Text>{item}</Text>
37 ))}
38
39 <Text>Unordered Inventory:</Text>
40 {character.inventory.map(item => (
41 <Text>{item}</Text>
42 ))}
43 </View>
44 );
45};
1const TraverseCharacterInventory = ({
2 characterName,
3}: {
4 characterName: string;
5}) => {
6 const realm = useRealm();
7 const [inventoryItem, setInventoryItem] = useState<string>('');
8 const [inventory, setInventory] = useState<string[]>([]);
9
10 const character = useQuery(
11 Character,
12 characters => {
13 return characters.filtered(`name = '${characterName}'`);
14 },
15 [characterName],
16 )[0];
17
18 const addInventoryItem = () => {
19 realm.write(() => {
20 character?.inventory.add(inventoryItem);
21 });
22 setInventory([...inventory, inventoryItem]);
23 };
24
25 return (
26 <View>
27 <Text>{character.name}</Text>
28 <Text>Add an item to the inventory:</Text>
29 <TextInput
30 onChangeText={text => setInventoryItem(text)}
31 value={inventoryItem}
32 />
33 <Button
34 title='Add Inventory Item'
35 onPress={addInventoryItem}
36 />
37
38 <Text>Ordered Inventory:</Text>
39 {inventory.map(item => (
40 <Text>{item}</Text>
41 ))}
42
43 <Text>Unordered Inventory:</Text>
44 {character.inventory.map(item => (
45 <Text>{item}</Text>
46 ))}
47 </View>
48 );
49};

Back

Dictionaries