public ref class CObjects : public IList
{
private:
int items;
array<Object ^> ^ objects;
public:
. . . No Change
virtual void RemoveAt(int);
};
. . . No Change
void CObjects::RemoveAt(int index)
{
if( (index >= 0) && (index < Count) )
{
for(int i = index; i < Count - 1; i++)
objects[i] = objects[i + 1];
items--;
}
}
Deleting an Item by its Value
|
|
The problem with deleting an item based on its index is
that, if you are not sure, you could delete the wrong item. An alternative is to
first precisely define the item you want to get rid it, and then hand the item
itself to the compiler that would remove it. To support this approach, the IList
interface is equipped with a method named Remove() and whose syntax is:
void Remove(Object^ value);
This method takes as argument the item to be deleted. This
means that the compiler will first look for the item in the list. If it finds
that item, it removes it. If there is no item like value, nothing happens
(the compiler doesn't throw an exception. Here is an example of implementing
this method:
public ref class CObjects : public IList
{
private:
int items;
array<Object ^> ^ objects;
public:
. . . No Change
virtual void Remove(Object ^);
};
. . . No Change
void CObjects::Remove(Object ^ value)
{
RemoveAt(IndexOf(value));
}
To remove all items from a list at once, you can implement Clear()
method of the IList interface. Its syntax is:
void Clear();
Here is an example of implementing it:
using namespace System;
using namespace System::Collections;
public ref class CObjects : public IList
{
private:
int items;
array<Object ^> ^ objects;
public:
CObjects();
virtual property int Count
{
int get() { return items; }
}
virtual property bool IsSynchronized
{
bool get() { return false; }
}
virtual property Object ^ SyncRoot
{
Object ^ get() { return this; }
}
virtual property bool IsFixedSize
{
bool get() { return false; }
}
virtual property bool IsReadOnly
{
bool get() { return false; }
}
virtual property Object ^ default[int]
{
Object ^ get(int index) { return objects[index]; }
void set(int index, Object ^ value)
{
objects[index] = value;
}
}
virtual void CopyTo(Array ^, int);
virtual IEnumerator ^ GetEnumerator(void);
virtual int Add(Object ^);
virtual void Insert(int, Object ^);
virtual bool Contains(Object ^);
virtual int IndexOf(Object ^);
virtual void RemoveAt(int);
virtual void Remove(Object ^);
virtual void Clear();
};
CObjects::CObjects()
{
items = 0;
objects = gcnew array<Object ^>(5);
}
IEnumerator ^ CObjects::GetEnumerator(void)
{
return nullptr;
}
void CObjects::CopyTo(Array ^ ary, int index)
{
}
int CObjects::Add(Object ^ value)
{
// Check whether there is still room in
// the array to add a new item
if( items < objects->Length )
{
// Since there is room, put the new item to the end
objects[items] = value;
// increase the number of items
items++;
// Return the index of the item that was added
return items - 1;
} // Since the item could not be added, return a negative index
else
return -1;
}
void CObjects::Insert(int index, Object ^ value)
{
// Just to be safe, make sure that
// 1. There is still room in the array for a new item
// 2. The index argument is lower than the current number of items
// 3. The index argument is not negative
if( (index >= 0) && (index < items) )
{
// Before inserting the new item, create room for it
for(int i = items; i > index - 1; i--)
objects[i+1] = objects[i];
// Put the new item in the space that was created
objects[index] = value;
// Since a new item has been added, increase the count
items++;
}
}
bool CObjects::Contains(Object ^ value)
{
for(int i = 0; i < Count; i++)
if( objects[i] == value )
return true;
return false;
}
int CObjects::IndexOf(Object ^ value)
{
for(int i = 0; i < Count; i++)
if( objects[i] == value )
return i;
return -1;
}
void CObjects::RemoveAt(int index)
{
if( (index >= 0) && (index < Count) )
{
for(int i = index; i < Count - 1; i++)
objects[i] = objects[i + 1];
items--;
}
}
void CObjects::Remove(Object ^ value)
{
RemoveAt(IndexOf(value));
}
void CObjects::Clear()
{
items = 0;
}
int main()
{
CObjects ^ collNames = gcnew CObjects;
String ^ name;
name = L"Anne Salmon";
collNames->Add(name);
name = L"Faustin Elmes";
collNames->Add(name);
name = L"Julius Pullman";
collNames->Add(name);
name = L"Bertrand Alexander";
collNames->Add(name);
name = L"Christian Voulzy";
collNames->Add(name);
name = L"Joan Lamm";
collNames->Add(name);
Console::WriteLine(L"Original List");
for(int i = 0; i < collNames->Count; i++)
Console::WriteLine(L"{0}", collNames[i]);
Console::WriteLine(L"<-><-><-><-><-><-><-><->");
name = L"Christian E. Voulzy";
if( collNames->Contains(name) )
Console::WriteLine(L"The item was found");
else
Console::WriteLine(L"The item was not found");
Console::WriteLine(L"<-><-><-><-><-><-><-><->");
name = L"Bertrand Alexander";
int index = collNames->IndexOf(name);
if( index >= 0 )
Console::WriteLine(L"The index of Bertrand Alexander is {0}", index);
else
Console::WriteLine(L"The item was not found");
Console::WriteLine(L"<-><-><-><-><-><-><-><->");
collNames->RemoveAt(2);
Console::WriteLine(L"After deleting an item");
for(int i = 0; i < collNames->Count; i++)
Console::WriteLine(L"{0}", collNames[i]);
Console::WriteLine(L"<-><-><-><-><-><-><-><->");
name = L"Faustin Elmes";
collNames->Remove(name);
Console::WriteLine(L"After deleting an item");
for(int i = 0; i < collNames->Count; i++)
Console::WriteLine(L"{0}", collNames[i]);
Console::WriteLine(L"<-><-><-><-><-><-><-><->");
collNames->Clear();
Console::WriteLine(L"After removing all items");
for(int i = 0; i < collNames->Count; i++)
Console::WriteLine(L"{0}", collNames[i]);
return 0;
}
This would produce:
Original List
Anne Salmon
Faustin Elmes
Julius Pullman
Bertrand Alexander
Christian Voulzy
<-><-><-><-><-><-><-><->
The item was not found
<-><-><-><-><-><-><-><->
The index of Bertrand Alexander is 3
<-><-><-><-><-><-><-><->
After deleting an item
Anne Salmon
Faustin Elmes
Bertrand Alexander
Christian Voulzy
<-><-><-><-><-><-><-><->
After deleting an item
Anne Salmon
Bertrand Alexander
Christian Voulzy
<-><-><-><-><-><-><-><->
After removing all items
Press any key to continue . . .
Practical
Learning: Removing Some Items From the Collection
|
|
- Access the Properties.cpp source file
- Implement the Remove(), the RemoveAt(), and the Clear() methods as
follows:
#include "Properties.h"
CProperties::CProperties(void)
: counter(0), cur(-1)
{
RentalProperties = gcnew array<Object ^>(5);
}
void CProperties::CopyTo(Array ^, int)
{
}
void CProperties::Reset()
{
cur = -1;
}
bool CProperties::MoveNext()
{
cur++;
if( cur < Count )
return true;
else
return false;
}
IEnumerator ^ CProperties::GetEnumerator(void)
{
return this;
}
// This method is used to add a new item to the collection
int CProperties::Add(Object ^ value)
{
// Find out if the array is getting too small for the next item(s)
// If it is, increase its size by 5
if( Count == RentalProperties->Length )
Array::Resize(RentalProperties, RentalProperties->Length + 5);
if( counter < RentalProperties->Length )
{
RentalProperties[counter] = value;
counter++;
return counter - 1;
}
else
return -1;
}
// This method can be used to insert an item at a
// certain position inside the collection
void CProperties::Insert(int index, Object ^ value)
{
if( (counter <= RentalProperties->Length) &&
(index < Count) &&
(index >= 0) )
{
counter++;
for(int i = Count - 1; i > index; i--)
RentalProperties[i] = RentalProperties[i - 1];
RentalProperties[index] = value;
}
}
// This method is used to find out whether the item
// passed as argument exists in the collection
bool CProperties::Contains(Object ^ value)
{
bool found = false;
for(int i = 0; i < Count; i++)
if( dynamic_cast<CRentalProperty ^>(
this[i])->Equals(dynamic_cast<CRentalProperty ^>(value)) )
found = true;
return found;
}
// This method is used to check whether the item passed as
// argument exists in the collection. If so, it returns its index
int CProperties::IndexOf(Object ^ value)
{
int custIndex = -1;
for(int i = 0; i < Count; i++)
{
if( dynamic_cast<CRentalProperty ^>(
this[i])->Equals(dynamic_cast<CRentalProperty ^>(value)) )
{
custIndex = i;
break;
}
}
return custIndex;
}
// This method is used to delete the item
// positioned at the index passed as argument
void CProperties::RemoveAt(int index)
{
if( (index >= 0) && (index < Count) )
{
for(int i = index; i < Count - 1; i++)
RentalProperties[i] = RentalProperties[i + 1];
counter--;
}
}
// This method first checks the existence of
// the item passed as argument. If the item exists,
// the method deletes it
void CProperties::Remove(Object ^ value)
{
RemoveAt(IndexOf(value));
}
// This methods deletes all items from the collection
void CProperties::Clear(void)
{
counter = 0;
}
// This method is used to get the property positioned
// at the index passed as argument
CRentalProperty ^ CProperties::Get(int index)
{
return dynamic_cast<CRentalProperty ^>(RentalProperties[index]);
}
|
- Access the Exercise.cpp source file and change it as follows:
#include "RentalProperty.h"
#include "Properties.h"
using namespace System;
int main()
{
CProperties ^ properties = gcnew CProperties;
CRentalProperty ^ rental = nullptr;
rental = gcnew CRentalProperty;
rental->PropertyCode = 737495;
rental->PropertyType = PropertyTypes::Apartment;
rental->PropertyCondition = PropertyConditions::Good;
rental->Bedrooms = 1;
rental->Bathrooms = 1;
rental->MonthlyRent = 950.00;
properties->Add(rental);
rental = gcnew CRentalProperty;
rental->PropertyCode = 293749;
rental->PropertyType = PropertyTypes::SingleFamily;
rental->PropertyCondition = PropertyConditions::Excellent;
rental->Bedrooms = 5;
rental->Bathrooms = 3.5;
rental->MonthlyRent = 2550.75;
properties->Add(rental);
rental = gcnew CRentalProperty;
rental->PropertyCode = 224006;
rental->PropertyType = PropertyTypes::Apartment;
rental->PropertyCondition = PropertyConditions::Excellent;
rental->Bedrooms = 2;
rental->Bathrooms = 1;
rental->MonthlyRent = 1250.55;
properties->Add(rental);
rental = gcnew CRentalProperty;
rental->PropertyCode = 197249;
rental->PropertyType = PropertyTypes::Townhouse;
rental->PropertyCondition = PropertyConditions::BadShape;
rental->Bedrooms = 4;
rental->Bathrooms = 2.5;
rental->MonthlyRent = 1750.65;
properties->Add(rental);
rental = gcnew CRentalProperty;
rental->PropertyCode = 592795;
rental->PropertyType = PropertyTypes::SingleFamily;
rental->PropertyCondition = PropertyConditions::Good;
rental->Bedrooms = 3;
rental->Bathrooms = 2.00;
rental->MonthlyRent = 1870.35;
properties->Add(rental);
int i = 1;
Console::WriteLine(L"<+> Solas Properties Rental <+>");
Console::WriteLine(L"<-> Properties Listing <->");
for each(CRentalProperty ^ prop in properties)
{
Console::WriteLine(L"-------------------------------");
Console::WriteLine(L"{0}. Property Details", i.ToString());
Console::WriteLine(L"Property #: {0}",
prop->PropertyCode);
Console::WriteLine(L"Property Type: {0}",
prop->PropertyType);
Console::WriteLine(L"Condition: {0}",
prop->PropertyCondition);
Console::WriteLine(L"Bedrooms: {0}",
prop->Bedrooms);
Console::WriteLine(L"Bathrooms: {0}",
prop->Bathrooms);
Console::WriteLine(L"Monthly Rent: {0}",
prop->MonthlyRent);
i++;
}
Console::WriteLine(L"================================");
CRentalProperty ^ item1 = gcnew CRentalProperty;
item1->PropertyCode = 293749;
item1->PropertyType = PropertyTypes::SingleFamily;
item1->PropertyCondition = PropertyConditions::Excellent;
item1->Bedrooms = 5;
item1->Bathrooms = 3.5;
item1->MonthlyRent = 2550.75;
Console::WriteLine(L"8--8--8--8--8--8--8--8--8--8--8--8--8--8--8");
Console::WriteLine(L"-=- Sample Property -=-");
Console::WriteLine(L"Property #: {0}",
item1->PropertyCode);
Console::WriteLine(L"Property Type: {0}",
item1->PropertyType);
Console::WriteLine(L"Condition: {0}",
item1->PropertyCondition);
Console::WriteLine(L"Bedrooms: {0}",
item1->Bedrooms);
Console::WriteLine(L"Bathrooms: {0}",
item1->Bathrooms);
Console::WriteLine(L"Monthly Rent: {0}",
item1->MonthlyRent);
Console::WriteLine(L"-------------------------------------------");
if( properties->Contains(item1) == true )
Console::WriteLine("That property already exists in the listing");
else
Console::WriteLine("The property was not found in our database");
Console::WriteLine(L"8--8--8--8--8--8--8--8--8--8--8--8--8--8--8");
CRentalProperty ^ item2 = gcnew CRentalProperty;
item2->PropertyCode = 290004;
item2->PropertyType = PropertyTypes::SingleFamily;
item2->PropertyCondition = PropertyConditions::Excellent;
item2->Bedrooms = 5;
item2->Bathrooms = 3.5;
item1->MonthlyRent = 2550.75;
Console::WriteLine(L"-=- Sample Property -=-");
Console::WriteLine(L"Property #: {0}",
item2->PropertyCode);
Console::WriteLine(L"Property Type: {0}",
item2->PropertyType);
Console::WriteLine(L"Condition: {0}",
item2->PropertyCondition);
Console::WriteLine(L"Bedrooms: {0}",
item2->Bedrooms);
Console::WriteLine(L"Bathrooms: {0}",
item2->Bathrooms);
Console::WriteLine(L"Monthly Rent: {0}",
item2->MonthlyRent);
Console::WriteLine(L"-------------------------------------------");
if( properties->Contains(item2) == true )
Console::WriteLine("That property already exists in the listing");
else
Console::WriteLine("The property was not found in our database");
Console::WriteLine(L"8--8--8--8--8--8--8--8--8--8--8--8--8--8--8");
CRentalProperty ^ item3 = gcnew CRentalProperty;
item3->PropertyCode = 224006;
item3->PropertyType = PropertyTypes::Apartment;
item3->PropertyCondition = PropertyConditions::Excellent;
item3->Bedrooms = 2;
item3->Bathrooms = 1;
item3->MonthlyRent = 1250.55;
Console::WriteLine(L"-=- Sample Property -=-");
Console::WriteLine(L"Property #: {0}",
item3->PropertyCode);
Console::WriteLine(L"Property Type: {0}",
item3->PropertyType);
Console::WriteLine(L"Condition: {0}",
item3->PropertyCondition);
Console::WriteLine(L"Bedrooms: {0}",
item3->Bedrooms);
Console::WriteLine(L"Bathrooms: {0}",
item3->Bathrooms);
Console::WriteLine(L"Monthly Rent: {0}",
item3->MonthlyRent);
Console::WriteLine(L"The index of this property is: {0}",
properties->IndexOf(item3));
Console::WriteLine(L"8--8--8--8--8--8--8--8--8--8--8--8--8--8--8");
properties->RemoveAt(2);
Console::WriteLine(L"After removing the 3rd item");
Console::WriteLine(L"-------------------------------");
Console::WriteLine(L"<+> Solas Properties Rental <+>");
Console::WriteLine(L"<-> Properties Listing <->");
for(int n = 0; n < properties->Count; n++)
{
CRentalProperty ^ prop =
dynamic_cast<CRentalProperty ^>(properties[n]);
Console::WriteLine(L"-------------------------------");
Console::WriteLine(L"{0}. Property Details", (n+1).ToString());
Console::WriteLine(L"Property #: {0}",
prop->PropertyCode);
Console::WriteLine(L"Property Type: {0}",
prop->PropertyType);
Console::WriteLine(L"Condition: {0}",
prop->PropertyCondition);
Console::WriteLine(L"Bedrooms: {0}",
prop->Bedrooms);
Console::WriteLine(L"Bathrooms: {0}",
prop->Bathrooms);
Console::WriteLine(L"Monthly Rent: {0}",
prop->MonthlyRent);
}
Console::WriteLine(L"================================");
CRentalProperty ^ item4 = gcnew CRentalProperty;
item4->PropertyCode = 293749;
item4->PropertyType = PropertyTypes::SingleFamily;
item4->PropertyCondition = PropertyConditions::Excellent;
item4->Bedrooms = 5;
item4->Bathrooms = 3.5;
item4->MonthlyRent = 2550.75;
properties->Remove(item4);
Console::WriteLine(L"After removing another item");
Console::WriteLine(L"-------------------------------");
Console::WriteLine(L"<+> Solas Properties Rental <+>");
Console::WriteLine(L"<-> Properties Listing <->");
for(int n = 0; n < properties->Count; n++)
{
CRentalProperty ^ prop =
dynamic_cast<CRentalProperty ^>(properties[n]);
Console::WriteLine(L"-------------------------------");
Console::WriteLine(L"{0}. Property Details", (n+1).ToString());
Console::WriteLine(L"Property #: {0}",
prop->PropertyCode);
Console::WriteLine(L"Property Type: {0}",
prop->PropertyType);
Console::WriteLine(L"Condition: {0}",
prop->PropertyCondition);
Console::WriteLine(L"Bedrooms: {0}",
prop->Bedrooms);
Console::WriteLine(L"Bathrooms: {0}",
prop->Bathrooms);
Console::WriteLine(L"Monthly Rent: {0}",
prop->MonthlyRent);
}
Console::WriteLine(L"================================");
properties->Clear();
Console::WriteLine(L"After removing all items");
Console::WriteLine(L"<+> Solas Properties Rental <+>");
Console::WriteLine(L"<-> Properties Listing <->");
for(int n = 0; n < properties->Count; n++)
{
CRentalProperty ^ prop =
dynamic_cast<CRentalProperty ^>(properties[n]);
Console::WriteLine(L"-------------------------------");
Console::WriteLine(L"{0}. Property Details", (n+1).ToString());
Console::WriteLine(L"Property #: {0}",
prop->PropertyCode);
Console::WriteLine(L"Property Type: {0}",
prop->PropertyType);
Console::WriteLine(L"Condition: {0}",
prop->PropertyCondition);
Console::WriteLine(L"Bedrooms: {0}",
prop->Bedrooms);
Console::WriteLine(L"Bathrooms: {0}",
prop->Bathrooms);
Console::WriteLine(L"Monthly Rent: {0}",
prop->MonthlyRent);
}
Console::WriteLine(L"================================");
return 0;
}
|
- Execute the application to see the result:
<+> Solas Properties Rental <+>
<-> Properties Listing <->
-------------------------------
1. Property Details
Property #: 737495
Property Type: Apartment
Condition: Good
Bedrooms: 1
Bathrooms: 1
Monthly Rent: 950
-------------------------------
2. Property Details
Property #: 293749
Property Type: SingleFamily
Condition: Excellent
Bedrooms: 5
Bathrooms: 3.5
Monthly Rent: 2550.75
-------------------------------
3. Property Details
Property #: 224006
Property Type: Apartment
Condition: Excellent
Bedrooms: 2
Bathrooms: 1
Monthly Rent: 1250.55
-------------------------------
4. Property Details
Property #: 197249
Property Type: Townhouse
Condition: BadShape
Bedrooms: 4
Bathrooms: 2.5
Monthly Rent: 1750.65
-------------------------------
5. Property Details
Property #: 592795
Property Type: SingleFamily
Condition: Good
Bedrooms: 3
Bathrooms: 2
Monthly Rent: 1870.35
================================
8--8--8--8--8--8--8--8--8--8--8--8--8--8--8
-=- Sample Property -=-
Property #: 293749
Property Type: SingleFamily
Condition: Excellent
Bedrooms: 5
Bathrooms: 3.5
Monthly Rent: 2550.75
-------------------------------------------
That property already exists in the listing
8--8--8--8--8--8--8--8--8--8--8--8--8--8--8
-=- Sample Property -=-
Property #: 290004
Property Type: SingleFamily
Condition: Excellent
Bedrooms: 5
Bathrooms: 3.5
Monthly Rent: 0
-------------------------------------------
The property was not found in our database
8--8--8--8--8--8--8--8--8--8--8--8--8--8--8
-=- Sample Property -=-
Property #: 224006
Property Type: Apartment
Condition: Excellent
Bedrooms: 2
Bathrooms: 1
Monthly Rent: 1250.55
The index of this property is: 2
8--8--8--8--8--8--8--8--8--8--8--8--8--8--8
After removing the 3rd item
-------------------------------
<+> Solas Properties Rental <+>
<-> Properties Listing <->
-------------------------------
1. Property Details
Property #: 737495
Property Type: Apartment
Condition: Good
Bedrooms: 1
Bathrooms: 1
Monthly Rent: 950
-------------------------------
2. Property Details
Property #: 293749
Property Type: SingleFamily
Condition: Excellent
Bedrooms: 5
Bathrooms: 3.5
Monthly Rent: 2550.75
-------------------------------
3. Property Details
Property #: 197249
Property Type: Townhouse
Condition: BadShape
Bedrooms: 4
Bathrooms: 2.5
Monthly Rent: 1750.65
-------------------------------
4. Property Details
Property #: 592795
Property Type: SingleFamily
Condition: Good
Bedrooms: 3
Bathrooms: 2
Monthly Rent: 1870.35
================================
After removing another item
-------------------------------
<+> Solas Properties Rental <+>
<-> Properties Listing <->
-------------------------------
1. Property Details
Property #: 737495
Property Type: Apartment
Condition: Good
Bedrooms: 1
Bathrooms: 1
Monthly Rent: 950
-------------------------------
2. Property Details
Property #: 197249
Property Type: Townhouse
Condition: BadShape
Bedrooms: 4
Bathrooms: 2.5
Monthly Rent: 1750.65
-------------------------------
3. Property Details
Property #: 592795
Property Type: SingleFamily
Condition: Good
Bedrooms: 3
Bathrooms: 2
Monthly Rent: 1870.35
================================
After removing all items
<+> Solas Properties Rental <+>
<-> Properties Listing <->
================================
Press any key to continue . . .
|
- Close the DOS window and return to your programming environment
|
|