セット - React Native SDK
バージョン realm@10.5.0
の新機能。
Realmセットは、一意の値のコレクションを保存できる特別なオブジェクトです。 RealmセットはJavaScript セット に基づいています は、単一のタイプの値のみを含めることができ、書込みトランザクション (write transaction)内でのみ変更できます。セットを使用すると、和集合、交差、2 つのセット間の差分を見つけるなどの数学操作を実行できます。これらの操作の実行の詳細については、 基本的なセット操作の実装 に関する MDN ドキュメントを参照してください。
Realm オブジェクトモデル
Realm オブジェクトモデルのプロパティ タイプは、次の 2 つの方法で Realm セットとして定義できます。
セットに含めるデータ型を指定し、その後に
<>
を指定します。より複雑なプロパティには、 オブジェクト表記 と
type
フィールドを使用します。
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 }
セットを使用したオブジェクトの作成
Realm Set プロパティを持つオブジェクトを作成するには、書込みトランザクション内でオブジェクトを作成する必要があります。 Realm オブジェクトを定義するときは、空の配列または初期値を含む配列を渡して Realm セットを初期化します。
例
CreateInitialCharacters
コンポーネントの次の例では、Set プロパティを持つCharacter
オブジェクトを作成しています。
CreateInitialCharacters
コンポーネントは次の処理を実行します。
コンポーネント内で
useRealm()
フックを呼び出すことで、開いている Realm インスタンスへのアクセスを取得します。React の useEffect 使用 フックを使用して、
useEffect
と空の依存関係配列を使用して匿名関数を 1 回だけ呼び出します。匿名関数内で、書込みトランザクション内に 2 つの異なるCharacter
オブジェクトを作成します。 各文字のinventory
とlevelsCompleted
セットを、初期値を持つ配列として設定します。Character
クラスをuseQuery()
フックに渡すことで、Realm インスタンス内のすべての文字を検索します。UI 内の各文字の名前を
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 };
セットに項目を追加する
セットに項目を追加するには、新しい値をRealm.Set.add() メソッドに 書込みトランザクション (write transaction) 内の メソッド メソッド。
例
AddInventoryToCharacter
コンポーネントの次の例では、文字のインベントリに新しいセット要素を追加しています。
AddInventoryToCharacter
コンポーネントは次の処理を実行します。
コンポーネント内で
useRealm()
フックを呼び出すことで、開いている Realm インスタンスへのアクセスを取得します。状態変数 を作成します これは、在庫セットに追加する新しい在庫アイテムを表す "inventaryItem" と呼ばれます。
Character
クラスをuseQuery()
フックに渡し、 Collection.filtered()メソッドを実行して、文字を検索します メソッドを使用して、名前が プロパティ と一致する文字をフィルタリングするcharacterName
。次に、変数character
を最初に一致する結果に設定します。inventoryItem
状態変数をRealm.Set.add()
に渡して、文字のインベントリにインベントリ アイテムを追加する書込みトランザクションを実行するコンポーネント メソッドaddInventoryItem()
を作成します。inventoryItem
状態変数を変更するTextInput
と、addInventoryItem()
メソッドを呼び出すButton
をレンダリングします。
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 };
セットに特定の項目が含まれているかどうか、およびセットのサイズを確認
サイズや特定のアイテムが含まれているかどうかなど、セットに関する情報を確認する必要がある場合があります。
セットに特定の値が含まれているかどうかを判断するには、値をRealm.Set.has() メソッドに 使用して複数のドキュメントを挿入できます。 このメソッドは、セットに指定された値が含まれている場合はtrue
を返します。
セットに含まれるアイテム数を確認するには、そのsize
プロパティを確認します。
例
QueryCharacterInventory
コンポーネントの次の例では、文字の在庫 サイズと特定のアイテムがあるかどうかを確認します。
QueryCharacterInventory
コンポーネントは次の処理を実行します。
状態変数 を作成します 文字のインベントリを検索する際に使用するインベントリ アイテムを表す "inventaryItem" と呼ばれます。
useQuery
フックを使用してすべての文字のクエリを実行し、結果をフィルタリングしてコンポーネントにcharacterName
プロパティ として渡される と一致する名前の文字のみを含めます。 。次に、最初の一致する結果が得られます。Character
クラスをuseQuery()
フックに渡し、 Collection.filtered()メソッドを実行して、文字を検索します メソッドを使用して、characterName
プロパティと一致する名前を持つ文字をフィルタリングします。 次に、変数character
を最初に一致する結果に設定します。inventoryItem
状態変数をRealm.Set.has()
に渡して、文字の在庫にアイテムが含まれているかどうかを確認するコンポーネント メソッドqueryCharacterInventory
を作成します。 文字の在庫にアイテムが含まれている場合、メソッド は 文字が アイテムを持っていることを確認します。文字の在庫にアイテムが含まれていない場合、メソッドは文字がアイテムを持っていないことをアラートします。文字の名前をレンダリングし、文字のインベントリの
size
プロパティを使用してインベントリ サイズをレンダリングします。 また、inventoryItem
状態変数を変更するTextInput
と、queryCharacterInventory
メソッドを呼び出すButton
もレンダリングします。
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 };
セット情報の削除
セットから特定の項目またはすべての項目を削除することができます。
セットから特定の値を削除するには、値をRealm.Set.delete() メソッドに 書込みトランザクション (write transaction) 内のメソッドです。
セットをクリアするには、 Realm.Set.client() 書込みトランザクション (write transaction) 内のメソッドです。
例
RemoveInventoryFromCharacter
コンポーネントの次の例では、セットから特定のアイテムを削除し、すべてのアイテムのセットをクリアします。
RemoveInventoryFromCharacter
コンポーネントは次の処理を実行します。
コンポーネント内で
useRealm()
フックを呼び出すことで、開いている Realm インスタンスへのアクセスを取得します。状態変数 を作成します 在庫セットから削除する在庫項目を表す "inventoryItem" と呼ばれます。
inventoryItem
状態変数をRealm.Set.delete()
に渡して文字のインベントリからアイテムを削除するコンポーネント メソッドremoveInventoryItem
を作成します。文字のインベントリからすべてのアイテムを削除するために
Realm.Set.clear()
を呼び出すコンポーネント メソッドremoveAllInventory
を作成します。状態変数を変更する と、それぞれ メソッドと メソッドを呼び出す
TextInput
2inventoryItem
Button
つのremoveInventoryItem
removeAllInventory
コンポーネントをレンダリングします。
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 };
セットを走査
Set を走査してセット内の各アイテムにアクセスできます。 セットを走査するには、Set.map()
メソッドまたは代替の 反復メソッドを使用します。
ただし、デフォルトでは、セット内の項目の順序は保証されません。 セットを順番に走査するには、セットの項目を 状態変数 に保存します セットに新しい項目を追加すると、その状態変数が更新されます。
例
TraverseCharacterInventory
コンポーネントの次の例では、文字はインベントリ アイテムなしで始まります。 ユーザーが在庫 セットにアイテムを追加すると、 コンポーネントにはセット内の各アイテムが順序付きリストと順序なしリストの両方に表示されます。
TraverseCharacterInventory
コンポーネントは次の処理を実行します。
コンポーネント内で
useRealm()
フックを呼び出すことで、開いている Realm インスタンスへのアクセスを取得します。在庫セットに追加する新しい在庫アイテムを表す "inventaryItem" という状態変数を作成します。
文字のインベントリ アイテムを挿入順に保持する「inventary」と呼ばれる状態変数を作成します。
Character
クラスをuseQuery()
フックに渡し、 Collection.filtered()メソッドを実行して、文字を検索します メソッドを使用して、名前が プロパティ と一致する文字をフィルタリングするcharacterName
。次に、変数character
を最初に一致する結果に設定します。状態変数をRealm.Set.add()に渡して、文字のインベントリにインベントリ アイテムを追加する書込みトランザクションを実行するコンポーネント メソッド
addInventoryItem()
inventoryItem
作成します 使用して複数のドキュメントを挿入できます。 書込みトランザクション後、メソッドはinventoryItem
をinventory
配列状態変数に追加します。inventoryItem
状態変数を変更するTextInput
と、addInventoryItem()
メソッドを呼び出すButton
をレンダリングします。inventory
配列状態変数を反復処理することで、セットに追加された順序で文字のインベントリ アイテムのリストをレンダリングします。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 };