1

I have a string[] array that is split by \r. Each row in the array has title|address in it, but every so often I end up with a duplicate of the address portion of it, which I don't want.

This:

Title1 | Address1 //[0]
Title2 | Address2 //[1]
Title3 | Address1 //[2]
Title4 | Address3 //[3]

Would become:

Title1 | Address1 //[0]
Title2 | Address2 //[1]
Title4 | Address3 //[2]

The array declaration is as follows: string[] resultsArray = results.Split('\r'); //Title|Address I then later split the row when I grab the individual elements by |.

Usage (extremely simplified):

foreach (string result in resultsArray)
{
    string splitResult[] = result.Split('|');
    title = splitResult[0];
    address = splitResult[1];
}
4
  • 2
    So if there is a duplicate address, you want to remove the title aswell? Have you tried using a Dictionary<string,string> instead? Commented Feb 14, 2011 at 21:29
  • Why did you remove Title3 and not Title1? Commented Feb 14, 2011 at 21:29
  • @moriartyn The OP is asking about a multi element array Commented Feb 14, 2011 at 21:30
  • @The Scrum Meister Oh, Thanks, I should have looked at it better. Commented Feb 14, 2011 at 21:31

5 Answers 5

5

I'm assuming the question is, how do you prevent duplicate addresses from being entered into the list. Could you use a Dictionary?

Dictionary<string, string> addresses = new Dictionary<string, string>();

foreach(string result in resultsArray)
{
    string splitResult[] = result.Split('|');

    // check to see if address already exists, if it does, skip it.
    if(!addresses.ContainsKey(splitResult[1]))
    {
        addresses.add(splitResult[1], splitResult[0]);
    }
}   
Sign up to request clarification or add additional context in comments.

2 Comments

Yes, your interpretation is a better one than my own. I ended up using: if (!resultsList.Exists(delegate(ResultsList r) { return r.title == splitResult[0]; }))
As I've been loading the results into a comprehensive list with other elements.
3
string[] strings = { "Title1 | Address1", "Title2 | Address2", "Title3 | Address1", "Title4 | Address3" };
var _strings = strings.GroupBy(s => s.Split('|')[1]).Select(g => g.Min(s => s));

Comments

2
var seenItBefore = new HashSet<string>();
foreach (string result in resultsArray)
{
    string splitResult[] = result.Split('|');
    title = splitResult[0];
    address = splitResult[1];

    if (!seenItBefore.Add(address)) continue;

    // process
}

You could also supply a projecting IEqualityComparer<string[]>to Distinct() if you're building up a vine of IEnumerable<>, but since your sample doesn't use it, I decided to stick with classic procedural.

2 Comments

The Add method returns a bool to indicate whether the item was already in the set, so you could just use if (!seenItBefore.Add(address)) { /* process */ } instead of the Contains/Add combo.
@LukeH I think you got the condition inverted, since Add returns true if the add succeeds. Incorporating the change, though.
1

Using John Skeet's ProjectionComparer, it becomes rather easy:

var comparer = new ProjectionComparer((string input) => input.Split('|')[1]);
var results = resultsArray.Distinct(comparer);

Comments

0

Try something like:

resultArray.Select(p => p.Split('|')).Select(p => new { Name = p[0], Address = p[1] }).GroupBy(p => p.Address).Select(p => p.First()).ToArray();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.