Trying to compare two lists c# - Should work? - c#

I have a method that looks like this:
GetDrawing(Dictionary<string, List<string>> AllDrawings, Dictionary<string, bool> ImportData, string[] ItemsToCompare)
Firstly, the method creates a new List<string> with all the items from ImportData<string, bool> that have the value true and can be found in string[] ItemsToCompare
Secondly, I would like to compare the new List<string> with the List from AllDrawings<string, List<string>>. The method is in the end supposed to return a string with the key from AllDrawings<string>, List<String>> where the two lists match.
I have now spent a lot of hours trying to figure this out myself and also tried every answer I could find to similar questions here on Stackoverflow but with no luck.
Below is the full code for my method. As mentioned above I've tried a lot of different methods to compare the lists but the one following below is the latest try.
public static string GetDrawing(Dictionary<string, List<string>> AllDrawings, Dictionary<string, bool> ImportData, string[] ItemsToCompare)
{
string FinalDrawing = "";
try
{
List<string> AllCorrect = new List<string>();
foreach (var item in ImportData)
{
if (item.Value == true && ItemsToCompare.Contains(item.Key))
AllCorrect.Add(item.Key);
}
AllCorrect.Sort();
foreach (var DrawItem in AllDrawings)
{
DrawItem.Value.Sort();
var match = AllCorrect.SequenceEqual(DrawItem.Value);
if (match == true)
{
FinalDrawing = DrawItem.Key;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return FinalDrawing;
}
My problem is that the return value from var match = AllCorrect.SequenceEqual(DrawItem.Value); is false and therefore the FinalDrawing is never set.
All answers are very appreciated.
Thanks in advance!

Ok.. I already said that in comments, but just to make sure that you don't get yelled at too much for not-using-linq and such:
your program seems correct up to the point you told us.
Here's a simple test. I provided some stub data that cover all things that you seem to check:
only true things from importedata
only things that are listed in itemstocompare
input lists are not sorted
-> http://rextester.com/HAE73942
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
public class Program
{
// your original function, nothing changed
public static string GetDrawing(Dictionary<string, List<string>> AllDrawings, Dictionary<string, bool> ImportData, string[] ItemsToCompare)
{
string FinalDrawing = "";
try
{
List<string> AllCorrect = new List<string>();
foreach (var item in ImportData)
{
if (item.Value == true && ItemsToCompare.Contains(item.Key))
AllCorrect.Add(item.Key);
}
AllCorrect.Sort();
foreach (var DrawItem in AllDrawings)
{
DrawItem.Value.Sort();
var match = AllCorrect.SequenceEqual(DrawItem.Value);
if (match == true)
{
FinalDrawing = DrawItem.Key;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return FinalDrawing;
}
public static void Main(string[] args)
{
var allDrawings = new Dictionary<string, List<string>>();
allDrawings.Add("aaa", new List<string>{ "a03", "a01", "a02" }); // originally unsorted
allDrawings.Add("bbb", new List<string>{ "b03", "b01", "b02" }); // originally unsorted
allDrawings.Add("ccc", new List<string>{ "c03", "c01", "c02" }); // originally unsorted
var import = new Dictionary<string, bool>();
import.Add("b01", false); // falsey
import.Add("a05", true); // not in comparison
import.Add("a03", true);
import.Add("c01", false); // falsey
import.Add("a02", true);
import.Add("a04", true); // not in comparison
import.Add("a01", true);
var toCompare = new string[9];
toCompare[0]="a01"; toCompare[1]="a02"; toCompare[2]="a03";
toCompare[3]="b01"; toCompare[4]="b02"; toCompare[5]="b03";
toCompare[6]="c01"; toCompare[7]="c02"; toCompare[8]="c03";
var result = GetDrawing(allDrawings, import, toCompare);
Console.WriteLine("Result: " + result);
}
}
it works fine and prints aaa as it should.
This means that you had to have overlooked something in the input data. Maybe some strings are uppercase/lowercase? Maybe some strings have whitespaces inside and others not?

This code :
List<string> AllCorrect = new List<string>();
foreach (var item in ImportData)
{
if (item.Value == true && ItemsToCompare.Contains(item.Key))
AllCorrect.Add(item.Key);
}
AllCorrect.Sort();
Can be reduced to :
List<string> AllCorect = ImportData.Where(vp =>
ItemsToCompare.Contains(vp.Key) && vp.Value).Select(vp => vp.Key).OrderBy(vp => vp).ToList();
To solve the second problem you can do :
return AllDrawings.First(l => l.Value.OrderBy(l2 => l2).SequenceEqual(AllCorect)).Key;
P.S.
If First() always throws an exception then it suggests that problem lays in how this lists are filled with values and this is a different question.
Example :
public static string GetDrawing(Dictionary<string, List<string>> AllDrawings, Dictionary<string, bool> ImportData, string[] ItemsToCompare)
{
List<string> AllCorect = ImportData.Where(vp =>
ItemsToCompare.Contains(vp.Key) && vp.Value).Select(vp => vp.Key).OrderBy(vp => vp).ToList();
return AllDrawings.First(l => l.Value.OrderBy(l2 => l2).SequenceEqual(AllCorect)).Key;
}
static void Main(string[] args)
{
List<string> list1 = new List<string>() { "one", "two", "three" };
List<string> list2 = new List<string>() { "five", "six", "seven" };
Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>()
{
{"first", list1}, {"second", list2}
};
string[] itemsToCompare = { "one", "two", "three" };
var dict2 = new Dictionary<string, bool>()
{
{"one", true},
{"two", true},
{"three", true}
};
var result = GetDrawing(dict, dict2, itemsToCompare);
Console.WriteLine(result);
}
Output : first

If the strings really match also for casing your code would be correct. I propose you inspect your string sequences - create an readable string and add appropriate break points. Also try to sort case-insensitive if that is what is missing here
AllCorrect.Sort(StringComparer.InvariantCultureIgnoreCase);
var AllCorrectInfo = string.Join(", ", AllCorrect.ToArray());
foreach (var DrawItem in AllDrawings)
{
DrawItem.Value.Sort();
var DrawItemInfo = string.Join(", ", DrawItem.Value.ToArray());
var match = AllCorrect.SequenceEqual(DrawItem.Value, StringComparer.InvariantCultureIgnoreCase);
if (match == true)
{
FinalDrawing = DrawItem.Key;
}
}

Related

C# How to Compare List<string[]> item to the next?

I have a List<string[]>, and I would like to compare the first array from the list to the next, then print the parts that are equal in both string arrays.
For instance:
public static void Main()
{
List<string[]> list = new List<string[]>();
string[] a = {"some", "random", "string"};
string[] b = {"some", "other", "random", "string"};
list.Add(a);
list.Add(b);
string[] difference = Compare(list);
}
public static string[] Compare (List<string[]> A)
{
//do something here
}
The end goal is to loop it to compare each string array to every other string array in the list.
Thanks in advance.
1. Find intersections of pairs of arrays in the list
private static IEnumerable<(string,string[])> Compare(List<(string Name,string[] Words)> lists)
{
for(int i = 0; i < lists.Count - 1; i++) {
var a = lists[i];
var b = lists[i + 1];
yield return ($"{a.Name}<->{b.Name}", a.Words.Intersect(b.Words).ToArray());
}
}
Test
Code
List<(string, string[])> list = new List<(string, string[])>();
string[] a = {"some", "random", "string"};
string[] b = {"some", "other", "random", "string"};
string[] c = {"some", "other2", "random", "string2"};
list.Add(("a", a));
list.Add(("b", b));
list.Add(("c", c));
foreach( var pair in Compare(list) )
Console.WriteLine($"{pair.Item1}: {string.Join(", ", pair.Item2)}");
Output
// .NETCoreApp,Version=v3.0
a<->b: some, random, string
b<->c: some, random
2. Find words in all arrays
private static string[] InAll(List<string[]> lists)
{
var inAll = new List<string>();
foreach(var list in lists ) {
foreach(var word in list) {
if(lists.All(l => l.Contains(word))) {
inAll.Add(word);
}
}
}
return inAll.Distinct().ToArray();
}
Test
Code
public static void Main(string[] args)
{
List<string[]> list = new List<string[]>();
string[] a = {"some", "random", "string"};
string[] b = {"some", "other", "random", "string"};
string[] c = {"some", "other2", "random", "string2"};
list.Add(a);
list.Add(b);
list.Add(c);
foreach( var inAll in InAll(list) ) Console.WriteLine(inAll);
}
Output
// .NETCoreApp,Version=v3.0
some
random
Let's implement (in general case) it with a help of Linq:
using System.Linq;
...
private static IEnumerable<T[]> Differences<T>(IEnumerable<IEnumerable<T>> source,
IEqualityComparer<T> comparer = null) {
if (null == source)
throw new ArgumentNullException(nameof(source));
if (null == comparer)
comparer = EqualityComparer<T>.Default;
if (null == comparer)
throw new ArgumentNullException(nameof(comparer),
$"No default comparer for {typeof(T).Name}");
Dictionary<T, int> prior = null;
foreach (var line in source) {
Dictionary<T, int> current = line
.GroupBy(item => item, comparer)
.ToDictionary(chunk => chunk.Key, chunk => chunk.Count(), comparer);
if (null != prior)
yield return current
.Where(item => prior.ContainsKey(item.Key))
.SelectMany(item => Enumerable
.Repeat(item.Key, Math.Min(item.Value, prior[item.Key])))
.ToArray();
prior = current;
}
}
Demo:
List<string[]> list = new List<string[]>() {
new [] { "some", "random", "string" },
new [] { "some", "other", "random", "string" },
new [] { "some", "some", "some" },
new [] { "some", "some", "other" },
new [] { "some", "other", "some" },
};
string demo = string.Join(Environment.NewLine, Differences(list)
.Select(line => string.Join(", ", line)));
Console.Write(demo);
Outcome:
some, random, string // 1st and 2nd strings
some // 2nd and 3d strings
some, some // 3d and 4th strings
some, some, other // 4th and 5th strings
If you want the 1st line only, add .FirstOrDefault():
string demo = Differences(list)
.Select(line => string.Join(", ", line))
.FirstOrDefault();
Console.Write(demo);
Outcome:
some, random, string
Finally, if you want to intersect all items (common items within all lines):
private static IEnumerable<T> IntersectAll<T>(IEnumerable<IEnumerable<T>> source,
IEqualityComparer<T> comparer = null) {
if (null == source)
throw new ArgumentNullException(nameof(source));
if (null == comparer)
comparer = EqualityComparer<T>.Default;
if (null == comparer)
throw new ArgumentNullException(nameof(comparer),
$"No default comparer for {typeof(T).Name}");
Dictionary<T, int> prior = null;
foreach (var line in source) {
Dictionary<T, int> current = line
.GroupBy(item => item, comparer)
.ToDictionary(chunk => chunk.Key, chunk => chunk.Count(), comparer);
if (null != prior)
prior = current
.Where(item => prior.ContainsKey(item.Key))
.ToDictionary(item => item.Key, item => Math.Min(item.Value, prior[item.Key]));
else
prior = current;
}
return (prior ?? new Dictionary<T, int>())
.SelectMany(item => Enumerable.Repeat(item.Key, item.Value));
}
For an arbitrary amount of lists to be compared you could write something like this:
public static string[] Compare (List<string[]> lists)
{
var temp = lists.First().ToList();
foreach(var l in lists)
{
temp = temp.Intersect(l).ToList();
}
return temp.ToArray();
}
This would result in
some
random
string
Of course you would add error handling in case of an empty list and so on...
public static string[] Compare(List<string[]> A)
{
string result = string.Empty;
foreach(string s in A[0])
{
if(A[1].Contains(s))
{
if(result==string.Empty)
{
result += s;
}
else
{
result += "," + s;
}
}
}
return result.Split(',');
}
It seems like you simply need the intersection of all the arrays:
private static string[] GetCommonElements(List<string[]> list)
{
if (!list.Any())
{
return Array.Empty<string>();
}
IEnumerable<string> result = list[0];
foreach (string[] collection in list.Skip(1))
{
result = result.Intersect(collection);
}
return result.ToArray();
}
Personally, I tried to solve the problem using linq, and I hope the code below can answer to your question .
Result :
public static IEnumerable<string> Compare(List<string[]> items)
{
var liste = new List<string>() ;
AddingElements(items, liste);
return liste.Distinct();
}
private static void AddingElements(List<string[]> items, List<string> liste)
{
items.Skip(1).ToList().ForEach((e) =>
{
liste.AddRange(e.Difference(items.First()));
});
}
public static string[] Difference(this string[] sourceArray, string[] stringArray)
{
return sourceArray.Where(e => stringArray.Contains(e))
.ToArray();
}

Iterate over dictionary values list in C# to check for specific key

I would like to iterate over dictionary values which is a list of strings in C# to check for all keys
Dictionary<string, List<string>> csvList = new Dictionary<string, List<string>>();
I want to check each key(string) in csvList and check if it exists in any values(List)
foreach(var events in csvList)
{
foreach(var action in csvList.Values) // But I want to loop through all the lists in dictionary, not just the list of event key
{
}
}
This is kind of strange but let's try to work through it. We don't usually want to iterate the keys of a dictionary. The reason to use one is we want to get the values very quickly if we already know the key.
In the spirit of answering the question, to iterate over a Dictionary's keys you have to use the Keys property. Note that nothing about the order of this collection is guaranteed.
var d = new Dictionary<string, int>();
d.Add("one", 1);
d.Add("two", 2);
foreach (var k in d.Keys) {
Console.WriteLine(k);
}
But I think maybe you had a problem and chose a Dictionary as the solution, then came here when that didn't work. What if the Dictionary isn't the problem?
It sounds like you have several List<string> instances and you're interested in if a particular list contains a particular string. Or maybe you want to know, "Which lists contain which string?" We can answer that with a dictionary structured slightly differently. I'm going to use arrays instead of lists because it's easier to type.
using System;
using System.Collections.Generic;
public class Program
{
private static void AddWord(Dictionary<string, List<int>> d, string word, int index) {
if (!d.ContainsKey(word)) {
d.Add(word, new List<int>());
}
d[word].Add(index);
}
private static List<int> GetIndexesForWord(Dictionary<string, List<int>> d, string word) {
if (!d.ContainsKey(word)) {
return new List<int>();
} else {
return d[word];
}
}
public static void Main()
{
var stringsToFind = new[] { "one", "five", "seven" };
var listsToTest = new[] {
new[] { "two", "three", "four", "five" },
new[] { "one", "two", "seven" },
new[] { "one", "five", "seven" }
};
// Build a lookup that knows which words appear in which lists, even
// if we don't care about those words.
var keyToIndexes = new Dictionary<string, List<int>>();
for (var listIndex = 0; listIndex < listsToTest.GetLength(0); listIndex++) {
var listToTest = listsToTest[listIndex];
foreach (var word in listToTest) {
AddWord(keyToIndexes, word, listIndex);
}
}
// Report which lists have the target words.
foreach (var target in stringsToFind) {
Console.WriteLine("Lists with '{0}':", target);
var indices = GetIndexesForWord(keyToIndexes, target);
if (indices.Count == 0) {
Console.WriteLine(" <none>");
} else {
var message = string.Join(", ", indices);
Console.WriteLine(" {0}", message);
}
}
}
}
foreach(var events in csvList)
{
foreach(var action in csvList.Values)
{
if (action.Contains(events.Key)) //Just use this, there is no point to iterate the list as you can use contains method
}
}

Dictionary with multiple keys isn't working as expected

I'm making a console program where I've got multiple values mapped to dictionary keyLookup. I'm using if commands that use the key to output some console.writeline = ("stuff"); but it only works if I have the value and the key the same (in the dictionary). I don't know why this is. I've been mucking about with list and foreach and some variables trying to figure out what I've done wrong but even though it continues to work how it works now it still doesn't work how I want.
Also if I have a word in my console.readline(); that isn't in my dictionary the whole thing crashes. Which I don't want, and I'm not sure of why its doing that either as at some point it didn't. Also my mathFunction dictionary works just how I want my keyLookup dictionary to work. Though I think the difference is in how I'm using a list to cross reference through keyLookup.
class MainClass
{
public static string Line;
static string foundKey;
public static void Main (string[] args)
{
while (true)
{
if (Line == null)
{Console.WriteLine ("Enter Input"); }
WordChecker ();
}
}
public static void WordChecker()
{
string inputString = Console.ReadLine ();
inputString = inputString.ToLower();
string[] stripChars = { ";", ",", ".", "-", "_", "^", "(", ")", "[", "]",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "\n", "\t", "\r" };
foreach (string character in stripChars)
{
inputString = inputString.Replace(character, "");
}
// Split on spaces into a List of strings
List<string> wordList = inputString.Split(' ').ToList();
// Define and remove stopwords
string[] stopwords = new string[] { "and", "the", "she", "for", "this", "you", "but" };
foreach (string word in stopwords)
{
// While there's still an instance of a stopword in the wordList, remove it.
// If we don't use a while loop on this each call to Remove simply removes a single
// instance of the stopword from our wordList, and we can't call Replace on the
// entire string (as opposed to the individual words in the string) as it's
// too indiscriminate (i.e. removing 'and' will turn words like 'bandage' into 'bdage'!)
while ( wordList.Contains(word) )
{
wordList.Remove(word);
}
}
// Create a new Dictionary object
Dictionary<string, int> dictionary = new Dictionary<string, int>();
// Loop over all over the words in our wordList...
foreach (string word in wordList)
{
// If the length of the word is at least three letters...
if (word.Length >= 3)
{
// ...check if the dictionary already has the word.
if ( dictionary.ContainsKey(word) )
{
// If we already have the word in the dictionary, increment the count of how many times it appears
dictionary[word]++;
}
else
{
// Otherwise, if it's a new word then add it to the dictionary with an initial count of 1
dictionary[word] = 1;
}
}
List<string> dicList = new List<string>();
dicList = dictionary.Keys.ToList ();
Dictionary<string, string> keyLookup = new Dictionary<string, string>();
keyLookup["hey"] = "greeting";
keyLookup["hi"] = "greeting";
keyLookup["greeting"] = "greeting";
keyLookup["math"] = "math";
keyLookup["calculate"] = "math";
keyLookup["equation"] = "math";
foundKey = keyLookup[word];
List<string> keyList = new List<string>();
foreach (string keyWord in dicList)
{
if(keyWord == foundKey)
{keyList.Add (keyWord); }
}
foreach (string mKey in keyList)
{
if(mKey == "greeting")
{Greetings ();}
if (mKey == "math")
{Math ();}
}
}
}
public static void Math()
{
Console.WriteLine ("What do you want me to math?");
Console.WriteLine ("input a number");
string input = Console.ReadLine ();
decimal a = Convert.ToDecimal (input);
Console.WriteLine("Tell me math function");
string mFunction = Console.ReadLine();
Console.WriteLine ("tell me another number");
string inputB = Console.ReadLine();
decimal b = Convert.ToDecimal (inputB);
Dictionary<string, string> mathFunction = new Dictionary<string, string>();
mathFunction["multiply"] = "multiply";
mathFunction["times"] = "multiply";
mathFunction["x"] = "multiply";
mathFunction["*"] = "multiply";
mathFunction["divide"] = "divide";
mathFunction["/"] = "divide";
mathFunction["subtract"] = "subtract";
mathFunction["minus"] = "subtract";
mathFunction["-"] = "subtract";
mathFunction["add"] = "add";
mathFunction["+"] = "add";
mathFunction["plus"] = "add";
string foundKey = mathFunction[mFunction];
if (foundKey == "add")
{
Console.WriteLine (a + b);
}
else if (foundKey == "subtract")
{
Console.WriteLine (a - b);
}
else if (foundKey == "multiply")
{
Console.WriteLine (a * b);
}
else if (foundKey == "divide")
{
Console.WriteLine (a / b);
}
else
{
Console.WriteLine ("not a math");
}
}
public static void Greetings()
{
Console.WriteLine("You said hello");
}
}'
You should iterate through the dictionary differently (Dont use ToList-Function).
Try this instead:
foreach (KeyValuePair kvp (Of String, String) In testDictionary)
{
Debug.WriteLine("Key:" + kvp.Key + " Value:" + kvp.Value);
}
And your application is crashing if the word doesn't match, because of this code (You're not creating a new entry that way):
// Otherwise, if it's a new word then add it to the dictionary with an initial count of 1
dictionary[word] = 1;
EDIT: I was wrong about that dictionary[word] = 1 would not create a new element. It's perfectly fine like this.
foundKey = keyLookup[word];
If word doesn't exist in keyLookup then it will crash.
string foundKey = mathFunction[mFunction];
if mFunction doesn't exist in mathFunction then it will crash.
If you're trying to make this a "conversational" program, then the word look-up is the most important part. You don't use predicates or LINQ, both can make string functions extremely easy. Currently you use a Dictionary. Why not use Lists for each keyword?
List<string> GreetingKeywords;
GreetingKeywords.Add("hello"); // ...
List<string> MathKeywords;
MathKeywords.Add("math"); // ...
foreach (var word in dicList)
{
if (GreetingKeywords.Contains(word))
{ Greetings(); }
if (MathKeywords.Contains(word))
{ Maths(); }
}
I'd suggest you read up on predicate and List/Dictionary functions such as Find, IndexOf, etc. etc. That knowledge is invaluable to C#.

How could I use LINQ to filter out strings starting with a variety of sub-strings?

Let's say I have var lines = IEnumerable<string>, and lines contains a variety of lines whose first 1..n characters exclude them from a process. E.g lines starting with '*', 'E.g.', 'Sample', etc.
The list of exclusion tokens is variable and known only at runtime, so
lines.Where(l => !l.StartsWith("*") && !l.StartsWith("E.g.") && ...
becomes somewhat problematic.
How could I achieve this?
With LINQ:
List<string> exceptions = new List<string>() { "AA", "EE" };
List<string> lines = new List<string>() { "Hello", "AAHello", "BHello", "EEHello" };
var result = lines.Where(x => !exceptions.Any(e => x.StartsWith(e))).ToList();
// Returns only "Hello", "BHello"
Try this:
List<string> lines = new List<string>(); //add some values
List<string> exclusion=new List<string>(); //add some values
var result = lines.Except(exclusion, new MyComparer());
Where:
public class MyComparer : IEqualityComparer<string>
{
public bool Equals(string x, string y) { return x.StartsWith(y); }
public int GetHashCode(string obj) { //some code }
}

Intersperse a List<> [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Extension method for Enumerable.Intersperse?
I have a List<string> like this:
"foo", "bar", "cat"
I want it to look like this:
"foo", "-", "bar", "-", "cat"
Is there a C# method that does that?
You can make an extension that returns an IEnumerable<T> with interspersed items:
public static class ListExtensions {
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> items, T separator) {
bool first = true;
foreach (T item in items) {
if (first) {
first = false;
} else {
yield return separator;
}
yield return item;
}
}
}
The advantage of this is that you don't have to clutter your list with the extra items, you can just use it as it is returned:
List<string> words = new List<string>() { "foo", "bar", "cat" };
foreach (string s in words.Intersperse("-")) {
Console.WriteLine(s);
}
You can of course get the result as a list if you need that:
words = words.Intersperse("-").ToList();
Here is an implementation out of my personal toolbox. It's more general than what you require.
For your particular example, you would write
var list = new List<string> { "foo", "bar", "cat" };
var result = list.InterleaveWith(Enumerable.Repeat("-", list.Count - 1));
See it in action.
public List<string> GetNewList(List<string> list, string s)
{
var result = new List<string>();
foreach (var l in list)
{
result.Add(l);
result.Add(s);
}
result.RemoveAt(result.Count - 1);
return result;
}
you can use this method to get you list
var result = GetNewList(str,"-");
Hah! I've just written something for just this purpose!
public static IEnumerable<T> Interleave<T>(params IEnumerable<T>[] arrays)
{
var enumerators = arrays.Select(array => array.GetEnumerator()).ToArray();
var finished = true;
do
{
finished = true;
foreach (var enumerator in enumerators)
{
if (enumerator.MoveNext())
{
yield return enumerator.Current;
finished = false;
}
}
} while (finished == false);
}
This will interleave the specified enumerables in the order you choose.
Then you just fill an enumerable with dashes and interleave that with the original array. It can do more complex things as well.
A while ago I wrote an extension method for this kind of thing:
public static IEnumerable<T>
Join<T>(this IEnumerable<T> src, Func<T> separatorFactory)
{
var srcArr = src.ToArray();
for (int i = 0; i < srcArr.Length; i++)
{
yield return srcArr[i];
if(i<srcArr.Length-1)
{
yield return separatorFactory();
}
}
}
You can use it as follows:
myList.Join(() => "-").ToList()
EDIT:
As pointed out, my previous code results to a string not an array of strings. So here's my edited code:
var list = new List<string> { "foo", "bar", "cat" };
var result = string.Join("-", list.Select(x => x.ToString()).ToArray());
string pattern = "(-)";
string[] test = Regex.Split(result, pattern);
foreach(var str in test)
Console.WriteLine(str);
Retained old code for comparison purposes:
var list = new List<string> { "foo", "bar", "cat" };
var result = string.Join("-", list.Select(x => x.ToString()).ToArray());
Console.WriteLine(result); // prints "foo-bar-cat
Refer to this post. Cheers!
Yes, its a custom method you would write:
List<string> AddDashesToList(List<string> list)
{
if(list.Count > 1)
{
var newList = new List<string>();
foreach(item in list)
{
newList.Add(item);
newList.Add("-");
}
newList.RemoveAt(newList.Count-1);
return newList;
}
else
{
return list;
}
}

Categories