|
|
Alright, so i got an array like this:
String[] Arr = { "A, B, C", "B, A, C", "C, A", "B, C, A", "D, A, N, V", "N, W, B, A"};
I am trying to extract unique values / remove duplicates from this array, so in the end the output will be like:
A, B, C, D, N, V, W
Now here is my function:
public static String[] Extract(String[] List)
{
String[] Output = null;
String Symbols = String.Empty;
String SymbolsHere = String.Empty;
foreach (String Text in List)
{
if (Text.Contains(","))
{
String[] Vals = Text.Split(new char[] { ',' });
foreach (String Val in Vals)
{
if (SymbolsHere.IndexOf(Val) == -1)
{
SymbolsHere += Val + " ";
Symbols += Val + ", ";
}
}
}
else
{
if (SymbolsHere.IndexOf(Text) == -1)
{
Symbols += Text + ", ";
SymbolsHere += Text + " ";
}
}
}
MessageBox.Show(Symbols);
return Output;
}
Well, this almost works, but...
Last messagebox shows "A, B, C, A, D, N, V, W" instead of "A, B, C, D, N, V, W", so as you can see, one extra "A" char gets into output and i got no idea why
Take a look at this part:
if (SymbolsHere.IndexOf(Val) == -1)
{
MessageBox.Show(SymbolsHere, Val);
SymbolsHere += Val + " ";
Symbols += Val + ", ";
}
So, like, if symbol has not been found in already collected symbols container, show
symbols container itself and a new symbol. But, at this moment app pops a msgbox with collection of syms: A B C and new symbol,
which is not found in our collection: A.
Its like, absurd - A is already there
What is wrong with this code? Thanks
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
Not sure what your specs are:
if by symbol you mean a single character, then you are doing it wrong as Split() will return lots of 2-character strings, since your input has spaces. You may want to add a Trim() somewhere.
if by symbol you mean arbitrary multi-character strings ("words"), then IndexOf() is not the right method, as it also reports partial matches (i.e. "Y+" is found in "XY+=").
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
|
|
|
|
|
Thank you! It was all about spaces. Trim() solved the issue.
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
First time when "A" is added to the output string, it is the first character in the array element. When it is added second time, it not "A" its " A" which gets added. You should be using trim to get rid of that additional characters.
Also, you can make use of LINQ to make your code compact. Here is something quick I came up with (not the most efficient way though):
String[] Arr = { "A, B, C", "B, A, C", "C, A", "B, C, A", "D, A, N, V", "N, W, B, A" };
string uniqueCharacters = string.Empty;
foreach (string str in Arr)
{
List<string> values = str.Split(',').Distinct().ToList();
values.ForEach(x => uniqueCharacters = !uniqueCharacters.Contains(x.Trim()) ? uniqueCharacters + "," + x : uniqueCharacters);
}
uniqueCharacters = uniqueCharacters.Remove(0, 1);
Make sure to consider the size of array. If it is too huge, you may want to use StringBuilder instead of plain concatenation.
|
|
|
|
|
Thanks, yes, that was it
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
Also (if v3.5 or newer) take a look at System.Collections.Generic.HashSet<T> .
|
|
|
|
|
Combining the excellent answers you already have into a one liner using Linq (if available in the .NET version you are using)
string[] vals = text.Split(',').Select(t => t.Trim()).Distinct().ToArray();
Edit: This will only ensure unique in each group separated by ','. The easiest way to get unique between all groups may be to combine all the string array elements into one string and perform this operation on the full string e.g.
string[] vals = string.Join(",", arr)
.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(t => t.Trim())
.Distinct()
.ToArray();
Not sure how efficient this is, but it works!
Dave
Binging is like googling, it just feels dirtier.
Please take your VB.NET out of our nice case sensitive forum.
Astonish us. Be exceptional. (Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
modified on Saturday, January 22, 2011 12:27 PM
|
|
|
|
|
Talking about efficiency, I read somewere on MSDN that, for generating a list of unique elements, the more efficient way is to use an HashSet (as PIEBALDconsult already said) instead of the Distinct extension method.
Something like this:
var query = string.Join(",", arr)
.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(t => t.Trim());
var set = new Hashset<string>
foreach (string item in query)
set.Add(item);
string[] vals = set.ToArray();
|
|
|
|
|
Hi, Friends. and Mr Danish
These following works very well in Windows XP but when I execute this class in Windows 7, it does'nt work.
Kindly check it and reply me.
Thank you
(Riaz)
class MAPI
{
public bool AddRecipientTo(string email)
{
return AddRecipient(email, HowTo.MAPI_TO);
}
public bool AddRecipientCC(string email)
{
return AddRecipient(email, HowTo.MAPI_TO);
}
public bool AddRecipientBCC(string email)
{
return AddRecipient(email, HowTo.MAPI_TO);
}
public void AddAttachment(string strAttachmentFileName)
{
m_attachments.Add(strAttachmentFileName);
}
public int SendMailPopup(string strSubject, string strBody)
{
return SendMail(strSubject, strBody, MAPI_LOGON_UI | MAPI_DIALOG);
}
public int SendMailDirect(string strSubject, string strBody)
{
return SendMail(strSubject, strBody, MAPI_LOGON_UI);
}
[DllImport("MAPI32.DLL")]
static extern int MAPISendMail(IntPtr sess, IntPtr hwnd, MapiMessage message, int flg, int rsv);
int SendMail(string strSubject, string strBody, int how)
{
MapiMessage msg = new MapiMessage();
msg.subject = strSubject;
msg.noteText = strBody;
msg.recips = GetRecipients(out msg.recipCount);
msg.files = GetAttachments(out msg.fileCount);
m_lastError = MAPISendMail(new IntPtr(0), new IntPtr(0), msg, how, 0);
if (m_lastError > 1)
MessageBox.Show("MAPISendMail failed! " + GetLastError(), "MAPISendMail");
Cleanup(ref msg);
return m_lastError;
}
bool AddRecipient(string email, HowTo howTo)
{
MapiRecipDesc recipient = new MapiRecipDesc();
recipient.recipClass = (int)howTo;
recipient.name = email;
m_recipients.Add(recipient);
return true;
}
IntPtr GetRecipients(out int recipCount)
{
recipCount = 0;
if (m_recipients.Count == 0)
return IntPtr.Zero;
int size = Marshal.SizeOf(typeof(MapiRecipDesc));
IntPtr intPtr = Marshal.AllocHGlobal(m_recipients.Count * size);
int ptr = (int)intPtr;
foreach (MapiRecipDesc mapiDesc in m_recipients)
{
Marshal.StructureToPtr(mapiDesc, (IntPtr)ptr, false);
ptr += size;
}
recipCount = m_recipients.Count;
return intPtr;
}
IntPtr GetAttachments(out int fileCount)
{
fileCount = 0;
if (m_attachments == null)
return IntPtr.Zero;
if ((m_attachments.Count <= 0) || (m_attachments.Count > maxAttachments))
return IntPtr.Zero;
int size = Marshal.SizeOf(typeof(MapiFileDesc));
IntPtr intPtr = Marshal.AllocHGlobal(m_attachments.Count * size);
MapiFileDesc mapiFileDesc = new MapiFileDesc();
mapiFileDesc.position = -1;
int ptr = (int)intPtr;
foreach (string strAttachment in m_attachments)
{
mapiFileDesc.name = Path.GetFileName(strAttachment);
mapiFileDesc.path = strAttachment;
Marshal.StructureToPtr(mapiFileDesc, (IntPtr)ptr, false);
ptr += size;
}
fileCount = m_attachments.Count;
return intPtr;
}
void Cleanup(ref MapiMessage msg)
{
int size = Marshal.SizeOf(typeof(MapiRecipDesc));
int ptr = 0;
if (msg.recips != IntPtr.Zero)
{
ptr = (int)msg.recips;
for (int i = 0; i < msg.recipCount; i++)
{
Marshal.DestroyStructure((IntPtr)ptr, typeof(MapiRecipDesc));
ptr += size;
}
Marshal.FreeHGlobal(msg.recips);
}
if (msg.files != IntPtr.Zero)
{
size = Marshal.SizeOf(typeof(MapiFileDesc));
ptr = (int)msg.files;
for (int i = 0; i < msg.fileCount; i++)
{
Marshal.DestroyStructure((IntPtr)ptr, typeof(MapiFileDesc));
ptr += size;
}
Marshal.FreeHGlobal(msg.files);
}
m_recipients.Clear();
m_attachments.Clear();
m_lastError = 0;
}
public string GetLastError()
{
if (m_lastError <= 26)
return errors[m_lastError];
return "MAPI error [" + m_lastError.ToString() + "]";
}
readonly string[] errors = new string[] {
"OK [0]", "User abort [1]", "General MAPI failure [2]", "MAPI login failure [3]",
"Disk full [4]", "Insufficient memory [5]", "Access denied [6]", "-unknown- [7]",
"Too many sessions [8]", "Too many files were specified [9]", "Too many recipients were specified [10]", "A specified attachment was not found [11]",
"Attachment open failure [12]", "Attachment write failure [13]", "Unknown recipient [14]", "Bad recipient type [15]",
"No messages [16]", "Invalid message [17]", "Text too large [18]", "Invalid session [19]",
"Type not supported [20]", "A recipient was specified ambiguously [21]", "Message in use [22]", "Network failure [23]",
"Invalid edit fields [24]", "Invalid recipients [25]", "Not supported [26]"
};
List<MapiRecipDesc> m_recipients = new List<MapiRecipDesc>();
List<string> m_attachments = new List<string>();
int m_lastError = 0;
const int MAPI_LOGON_UI = 0x00000001;
const int MAPI_DIALOG = 0x00000008;
const int maxAttachments = 20;
enum HowTo { MAPI_ORIG = 0, MAPI_TO, MAPI_CC, MAPI_BCC };
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiMessage
{
public int reserved;
public string subject;
public string noteText;
public string messageType;
public string dateReceived;
public string conversationID;
public int flags;
public IntPtr originator;
public int recipCount;
public IntPtr recips;
public int fileCount;
public IntPtr files;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiFileDesc
{
public int reserved;
public int flags;
public int position;
public string path;
public string name;
public IntPtr type;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiRecipDesc
{
public int reserved;
public int recipClass;
public string name;
public string address;
public int eIDSize;
public IntPtr entryID;
}
|
|
|
|
|
When you say "It doesn't work" Do you mean it gives an error?
If so, what error message does it give?
If not, what does it do / not do?
Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.
|
|
|
|
|
Yes, It shows error.
Error is:
"MapiSendMail failed! General Mapi failure [2]"
|
|
|
|
|
Throw people a bone here. There is a lot of code. Which line throws the error?
BTW: You should have added this to your previous thread, below. Not started a new one.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
I wouldn't let CG touch my Abacus!
|
|
|
|
|
MAPI and CDO 1.21 are not supported in .NET. See this[^]. Yes, I know the code seems to be right, and it mignt seem to be working fine, but problems will arise when your solution is in production and under a little stress.
|
|
|
|
|
Given these interfaces:
interface IThing {
void Initialize(int value1, int value2);
int Result { get; }
}
interface IThingManager {
void AddThing(string groupName, IThing thingToAdd);
int Sum(string groupName);
int TotalSum();
void Print();
}
Write an implementation of the interfaces in these concrete classes:
class MultiplierThing : IThing { ... }
class AdderThing : IThing { ... }
class ThingManager : IThingManager {
...
void Print() { ... }
}
Example Ouput
Given a main program like this:
IThingManager manager = new VerboseThingManager();
IThing t;
t = new MultiplierThing();
t.Initialize(1, 2);
manager.AddThing("Group A", t);
t = new MultiplierThing();
t.Initialize(3, 4);
manager.AddThing("Group B", t);
t = new AdderThing();
t.Initialize(5, 6);
manager.AddThing("Group A", t);
t = new AdderThing();
t.Initialize(7, 8);
manager.AddThing("Group B", t);
manager.Print();
The corresponding output should be:
Group A:
- 2
- 11
Group B:
- 12
- 15
Sum of Group A = 13
Sum of Group B = 27
Total sum = 40
Please Help me
i made the classes of adderthing & MultiplierThing that inherits from interface IThing and stop
|
|
|
|
|
You just need to implement the interface methods as you have defined them. Thus in each class your Initialize() method should store your variables (this could be done in a base class) and your Result() method should return the sum, product, difference etc as appropriate.
I must get a clever new signature for 2011.
|
|
|
|
|
i konw but i can't do the implementation of
second interface
interface IThingManager
|
|
|
|
|
please i want the implementation of IThingManager Please
|
|
|
|
|
I'll give you a partial implementation. Since it's you homework, do the rest yourself.
public class ThingManager : IThingManager
{
Dictionary<string, List<IThing>> things = new Dictionary<string, List<IThing>>();
public void AddThing(string groupName, IThing thingToAdd)
{
if (!things.ContainsKey(groupName))
{
things.Add(groupName, new List<IThing>());
}
things[groupName].Add(thingToAdd);
}
}
Cheers
If you can read this, you don't have Papyrus installed
|
|
|
|
|
thaaaaanx alot Estys
but i can't complete because i didn`t deal with collections before
and don`t know how to implement the method sum
how to add items in gruopname
and how to read from user to add in groupname
sorry
|
|
|
|
|
Collections are dead easy
The example I gave you already adds things to your group.
To iterate over a collection use foreach :
public int Sum(string groupName)
{
int retValue = 0;
foreach (IThing ithing in things[groupName])
{
retValue += ithing.Result;
}
return retValue;
}
You can do the same for TotalSum. The only difference is to iterate over the things groupNames with KeyValues
Cheers
If you can read this, you don't have Papyrus installed
|
|
|
|
|
Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.
|
|
|
|
|
Estys wrote: If you can read this, you don't have Papyrus installed
I DO have Papyrus installed and can still read it. Now what?
|
|
|
|
|
You're just being flippant
If you can read this, you don't have Papyrus installed
|
|
|
|
|
See my answer above.
Cheers
If you can read this, you don't have Papyrus installed
|
|
|
|
|