-2

I have a list of 5 arbitrary user-inputted strings:

List<string> original = new List<string>() {"a", "a1", "a2", "b", "b1"} ;

For each string in the original collection, I want to get back the shortest string in the list which starts the current string:

"a" -> "a"
"a1" -> "a"
"a2" -> "a"
"b" -> "b"
"b1" -> "b"

How can I do this using LINQ?

Some more examples:

{a, ghjkjajj,hkj,bn,n} => {a, ghjkjajj,hkj,bn,n}
{ghj465,abn,abn1,hj,ui} => {ghj465,abn,abn,hj,ui}
{gh465,gh1,gh} => {gh,gh,gh}
{abcd,ab} => {ab,ab}
Zev Spitz
  • 13,950
  • 6
  • 64
  • 136
user2630764
  • 624
  • 1
  • 8
  • 19
  • so... it's just a matter of truncating the number from the name? – Kevin Gosse Oct 07 '16 at 06:31
  • 2
    Yes , but if the sequence is {a,a1,c34,b,b1} I need {a,a,c34,b,b} – user2630764 Oct 07 '16 at 06:33
  • http://stackoverflow.com/a/1657293/1982631 – Manoz Oct 07 '16 at 06:35
  • @Manoz: I need it to be generic , the input is not static , sometimes it can be {c34} othertime {fg,fg56,jk} – user2630764 Oct 07 '16 at 06:37
  • 1
    A Linq query for this would be hard to read and inefficient. Better use a good old `foreach` loop with a `HashSet` to keep track of previously added items – Kevin Gosse Oct 07 '16 at 06:40
  • @KooKiz _A Linq query for this would be hard to read and inefficient._ Please clarify. – Zev Spitz Oct 07 '16 at 07:13
  • On what basis do you include `c34` as-is, but map `a1` to `a`? Please edit this information into your question. – Zev Spitz Oct 07 '16 at 07:15
  • So `gh465`, `gh1` and `gh` would all map to `gh`. Would `gh465` map to `gh46` also? Or only `gh4651` maps to `gh465`? (Again, please edit this information into your question.) – Zev Spitz Oct 07 '16 at 07:27
  • @ZevSpitz {gh465,gh1,gh} => {gh,gh,gh} – user2630764 Oct 07 '16 at 07:29
  • And what about pure letter sequences: `{"abcd", "ab"}` => `{"ab", "ab"}` ? (Your question doesn't describe all these details; please edit into the question.) – Zev Spitz Oct 07 '16 at 07:32
  • @ZevSpitz : {"abcd", "ab"} => {"abcd", "ab"} – user2630764 Oct 07 '16 at 07:35
  • @S.Akbari Because it's a string comparison based on other values. If this value starts with any other value, return that other value; otherwise return it as is. – Zev Spitz Oct 07 '16 at 07:51
  • @ZevSpitz Hard to read because it's pretty much impossible to guess the intent just by reading the query. Inefficient because it's a solution of o(n²) complexity, where we could reach o(n log n) using a foreach loop with a HashSet – Kevin Gosse Oct 07 '16 at 08:12

2 Answers2

2

Since there are going to be no more than 5 strings at a time, efficiency is not a concern here.

var original = new List<string>() {"a","a1","c34","b","b1"};
var mapped = original.Select(x => original.Where(y => x.StartsWith(y)).Min()).ToList();

Note also that the comparison is case-sensitive; this can be fixed by passing in the appropriate StringComparison argument.

Zev Spitz
  • 13,950
  • 6
  • 64
  • 136
1

This code works for me:

var res = original.Select(c => c.Replace(c.Length == 2 ? c[1] : ' ', ' ')).ToList();

Input:

{ "a", "a1", "c34","a2", "b", "b1" } or {"a", "a1", "a2", "b", "b1"}

Output:

{ "a", "a", "c34","a", "b", "b" } or {"a", "a", "a", "b", "b"}

Salah Akbari
  • 39,330
  • 10
  • 79
  • 109
  • You can use a multi-line lambda statement for clarity, as this question involves LINQ to Objects and `IEnumerable`, not `IQueryable`. – Zev Spitz Oct 07 '16 at 07:09
  • 2
    I guess this wouldn't work for the input (mentioned in the comments) of {fg,fg56,jk} ? – David_001 Oct 07 '16 at 07:10
  • @David_001 I think the behavior for `fg56` is like `c34` as OP mentioned in comments because he didn't said `fg56` should be mapped to `fg`! – Salah Akbari Oct 07 '16 at 07:14
  • Also, will this holds good for {test,test1,nothing} to {{test,test,nothing} as OP mentions it as dynamic – user1400915 Oct 07 '16 at 07:18
  • 1
    This is a good code, may need additional conditions like Alphabet check at a given index, based on use cases. Not possible to cover all undefined use cases +1 – Mrinal Kamboj Oct 07 '16 at 07:19
  • @user1400915 I've provided the answer based on the OP's expected output that mentioned in his/her original post and also comments. We can't provide a complete answer until he/she has a common pattern for mapping. For example are you sure `test1` should be `test`? because he/she didn't mentioned it explicitly. – Salah Akbari Oct 07 '16 at 07:23