Conjuntos - React Native SDK
Nesta página
Novidades na versão realm@10.5.0
.
Um Conjunto de Realm é um objeto especial que permite armazenar uma coleção de valores únicos. Os conjuntos de Realm são baseados em conjuntos JavaScript{ , mas só pode conter valores de um único tipo e só pode ser modificado dentro de uma transação de gravação. Os conjuntos permitem que você realize operações matemáticas, como encontrar a união, interseção ou diferença entre dois conjuntos. Para saber mais sobre como executar essas operações, consulte os documentos MDN para Implementação de operações básicas definidas.
Realm Object Models
Você pode definir um tipo de propriedade de modelo de objeto Realm como um Conjunto de Realm de duas maneiras:
Especifique o tipo de dados que o conjunto conterá, seguido por
<>
.Use a notação de objeto e o campo
type
para propriedades mais complicadas.
1 class 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 }
1 class 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 }
Criar um objeto com um conjunto
Para criar um objeto com uma propriedade Realm Set, você deve criar o objeto dentro de uma transação de escrita. Ao definir seu Objeto de Realm, inicialize o Realm Set passando uma array vazia ou uma array com seus valores iniciais.
Exemplo
No exemplo a seguir de um componente CreateInitialCharacters
, criamos objetos Character
com propriedades Set.
O componente CreateInitialCharacters
faz o seguinte:
Consegue acesso a uma instância de realm aberta chamando o hook
useRealm()
dentro do componente.Utiliza o useEffect do React hook para chamar uma função anônima somente uma vez com
useEffect
e uma array de dependência vazia. Na função anônima, criamos dois objetosCharacter
diferentes dentro de uma transação escrita. Definimos os conjuntosinventory
elevelsCompleted
cada caractere como uma array com valores iniciais.Recupera todos os caracteres na instância do domínio passando a classe
Character
para o ganchouseQuery()
.Exibe o nome de cada caractere na interface do usuário como um elemento
Text
.
1 const 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 };
1 const 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 };
Adicionar itens a um conjunto
Para adicionar um item a um conjunto, passe o novo valor para o método Realm.Set.add() dentro de uma transação de gravação.
Exemplo
No exemplo a seguir de um componente AddInventoryToCharacter
, adicionamos novos elementos de conjunto ao inventário do caractere.
O componente AddInventoryToCharacter
faz o seguinte:
Consegue acesso a uma instância de realm aberta chamando o hook
useRealm()
dentro do componente.Cria uma variável de estado chamada "inventoryItem" que representa o novo item de inventário a ser adicionado ao conjunto de inventário.
Recupera o caractere passando a classe
Character
para o ganchouseQuery()
e executando o método Collection.filtered() método no resultado para filtrar caracteres com o nome correspondente aocharacterName
prop. Então definimos a variávelcharacter
para o primeiro resultado correspondente.Cria um método de componente
addInventoryItem()
que executa uma transação de gravação que adiciona um item de inventário ao inventário do personagem passando a variável de estadoinventoryItem
paraRealm.Set.add()
.Apresenta um
TextInput
que altera a variável de estado doinventoryItem
e umButton
que chama o métodoaddInventoryItem()
.
1 const 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 };
1 const 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 };
Verificar se um conjunto tem itens específicos e verificar o tamanho de um conjunto
Talvez você queira verificar se há informações sobre o seu Conjunto, como o tamanho ou se ele contém um item específico.
Para determinar se um conjunto contém um valor específico, passe o valor para o método Realm.Set.has() método. Esse método retornará true
se o conjunto contiver o valor especificado.
Para descobrir quantos itens estão em um Conjunto, você pode verificar sua propriedade size
.
Exemplo
No exemplo a seguir de um componente QueryCharacterInventory
, verificamos o tamanho do inventário do personagem e se ele tem um item específico.
O componente QueryCharacterInventory
faz o seguinte:
Cria uma variável de estado chamada "inventoryItem" que representa o item de inventário para o qual você deseja pesquisar o inventário do personagem.
Usa o hook
useQuery
para realizar uma consulta de todos os caracteres e filtrar os resultados para incluir apenas os caracteres com o nome correspondente aocharacterName
passado para o componente como uma propriedade. Em seguida, obtemos o primeiro resultado correspondente.Recupera o caractere passando a classe
Character
para o ganchouseQuery()
e executando o método Collection.filtered() no resultado para filtrar os caracteres com o nome correspondente à propriedadecharacterName
. Então definimos a variávelcharacter
para o primeiro resultado correspondente.Cria um método componente
queryCharacterInventory
que passa a variável de estadoinventoryItem
paraRealm.Set.has()
para verificar se o inventário do personagem contém o item. Se o inventário do caractere contiver o item, o método alertará que o caractere tem o item. Se o inventário do caractere não contiver o item, o método alertará que o caractere não tem o item.Distribui o nome do personagem e renderiza o tamanho do inventário utilizando a propriedade
size
do inventário do personagem. Ele também renderiza umTextInput
que altera a variável de estado doinventoryItem
e umButton
que chama o métodoqueryCharacterInventory
.
1 const 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 };
1 const 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 };
Remover informações do conjunto
Você pode querer remover um item específico ou todos os itens de um conjunto.
Para remover um valor específico de um conjunto, passe o valor para o método Realm.Set.delete() dentro de uma transação de gravação.
Para limpar o conjunto, execute o método Realm.Set.clear() dentro de uma transação de gravação.
Exemplo
No exemplo a seguir de um componente RemoveInventoryFromCharacter
, removemos um item específico do conjunto e limpamos o conjunto de todos os itens.
O componente RemoveInventoryFromCharacter
faz o seguinte:
Consegue acesso a uma instância de realm aberta chamando o hook
useRealm()
dentro do componente.Cria uma variável de estado chamada "inventoryItem" que representa o item de inventário a ser removido do conjunto de inventário.
Cria um método de componente
removeInventoryItem
que passa a variável de estadoinventoryItem
paraRealm.Set.delete()
a fim de remover o item do inventário do personagem.Cria um método de componente
removeAllInventory
que chamaRealm.Set.clear()
para remover todos os itens do inventário do personagem.Renderiza um
TextInput
que altera a variável de estadoinventoryItem
e dois componentesButton
que chamam os métodosremoveInventoryItem
eremoveAllInventory
, respectivamente.
1 const 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 };
1 const 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 };
Percorrer um conjunto
Você pode percorrer um conjunto para acessar cada item no conjunto. Para percorrer um Set, use o método Set.map()
ou o método de iteração alternativo.
No entanto, por padrão, o pedido dos itens em um conjunto não é garantido. Para percorrer um conjunto em ordem, você pode armazenar os itens do conjunto em uma variável de estado e atualizar essa variável de estado ao adicionar novos itens ao conjunto.
Exemplo
No exemplo seguinte de um componente TraverseCharacterInventory
, um caractere começa sem itens de inventário. Quando o usuário adiciona itens ao conjunto de inventário, o componente exibe cada item no conjunto em uma lista ordenada e não ordenada.
O componente TraverseCharacterInventory
faz o seguinte:
Consegue acesso a uma instância de realm aberta chamando o hook
useRealm()
dentro do componente.Cria uma variável de estado chamada "inventoryItem" que representa o novo item de inventário para adicionar ao conjunto de inventário.
Cria uma variável de estado chamada "inventário" que manterá os itens de inventário do personagem em ordem de inserção.
Recupera o caractere passando a classe
Character
para o ganchouseQuery()
e executando o método Collection.filtered() método no resultado para filtrar caracteres com o nome correspondente aocharacterName
prop. Então definimos a variávelcharacter
para o primeiro resultado correspondente.Cria um método de componente
addInventoryItem()
que executa uma transação de gravação que adiciona um item de inventário ao inventário do personagem passando a variável de estadoinventoryItem
para o Realm.Set.add() método. Após a transação de gravação, o método adiciona oinventoryItem
à variável de estado da arrayinventory
.Apresenta um
TextInput
que altera a variável de estado doinventoryItem
e umButton
que chama o métodoaddInventoryItem()
.Renderiza uma lista dos itens de inventário do caractere na ordem em que foram adicionados ao Conjunto, iterando por meio da variável de estado da array
inventory
.Renderiza uma lista não ordenada do inventário do personagem iterando por
character.inventory
.
1 const 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 };
1 const 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 };