[Question]
  [
Given a string, find the first word starting with each letter (case insensitive).
### Sample
Using `Ferulas flourish in gorgeous gardens.` as input:
```
"Ferulas flourish in gorgeous gardens."
 ^^^^^^^          ^^ ^^^^^^^^
 |                |  |
 |                |  --> is the first word starting with `g`
 |                --> is the first word starting with `i`
 --> is the first word starting with `f`
```
Then, the output for this sample should be the matched words joined by one single space:
```
"Ferulas in gorgeous"
```
### Challenge
Both input and output must be a string representation, or the closest alternative in your language.
Program or function allowed.
You can consider a word being at least one of: `lowercase or uppercase letters, digits, underscore`.
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), shortest answer in bytes wins.
### Another samples:
```
input: "Take all first words for each letter... this is a test"
output: "Take all first words each letter is"
```
---
```
input: "Look ^_^ .... There are 3 little dogs :)"
output: "Look _ There are 3 dogs"
```
---
```
input: "...maybe some day 1 plus 2 plus 20 could result in 3"
output: "maybe some day 1 plus 2 could result in 3"
```
  
[Answer]
# [Retina](https://github.com/mbuettner/retina/wiki/The-Language), 28 bytes:
```
M!i`\b(\w)(?<!\b\1.+)\w*
¶
 
```
* `M!` - Match each work and print all words separated by newlines.
* `i` - Ignore case.
* `\b(\w)` - Capture first letter of each word
* `(?<!\b\1.+)` - After matching the letter, check if there wasn't a previous word starting with the same letter. `\1.+` ensures at least two characters, so we are skipping the current word.
* `\w*` - match the rest of the word.  
The above matches only words - all other characters are removed.
* `¶\n`  - Replace newlines with spaces.
[Try it online!](http://retina.tryitonline.net/#code=TSFpYFxiKFx3KSg_PCFcYlwxLispXHcqCsK2CiA&input=Li4ubWF5YmUgc29tZSBkYXkgMSBwbHVzIDIgcGx1cyAyMCBjb3VsZCByZXN1bHQgaW4gMw)
[Answer]
## [Retina](https://github.com/mbuettner/retina), 45 bytes
```
i`\b((\w)\w*)\b(?<=\b\2\w*\b.+)
\W+
 
^ | $
```
Simply uses a single regex to remove later words starting with the same `\w` character (case insensitive with the `i` option), converts runs of `\W` to a single space, then removes any leading/trailing space from the result.
[Try it online!](http://retina.tryitonline.net/#code=aWBcYigoXHcpXHcqKVxiKD88PVxiXDJcdypcYi4rKQoKXFcrCiAKXiB8ICQK&input=VGhpcyBpcyBhIGxvbmdlciB0ZXN0IHdpdGggc2luZ2xlIGxldHRlciB3b3JkcywgbnVtYmVycyBsaWtlIDIsIDMwMCwgMjAsIC01LCAzIGFuZCA1MiwgYW5kIG1vcmUuIEkgYWxzbyBzdGFydCB0aGlzIHNlY29uZCBzZW50ZW5jZSBhcyBhbiBleGN1c2UgdG8gYWRkIGFub3RoZXIgc2luZ2xlIGxldHRlciB3b3JkLiBvX08gT2ggYm95Lg)
Edit: See [@Kobi's answer](https://codegolf.stackexchange.com/a/77273/21487) for a shorter version using `M!``
[Answer]
# JavaScript (ES6), ~~73~~ 71 bytes
```
s=>s.match(u=/\w+/g).filter(w=>u[n=parseInt(w[0],36)]?0:u[n]=1).join` `
```
*Saved 2 bytes thanks to @edc65!*
## Test
```
var solution = s=>s.match(u=/\w+/g).filter(w=>u[n=parseInt(w[0],36)]?0:u[n]=1).join` `;
var testCases = [
  "Ferulas flourish in gorgeous gardens.",
  "Take all first words for each letter... this is a test",
  "Look ^_^ .... There are 3 little dogs :)",
  "...maybe some day 1 plus 2 plus 20 could result in 3"
];
document.write("<pre>"+testCases.map(t=>t+"\n"+solution(t)).join("\n\n")+"</pre>");
```
[Answer]
# Pyth, 23 bytes
```
J:z"\w+"1jdxDJhM.grhk0J
```
Try it online: [Demonstration](http://pyth.herokuapp.com/?code=J%3Az%22%5Cw%2B%221jdxDJhM.grhk0J&input=Take%20all%20first%20words%20for%20each%20letter...%20this%20is%20a%20test&test_suite_input=Take%20all%20first%20words%20for%20each%20letter...%20this%20is%20a%20test%0ALook%20%5E_%5E%20....%20There%20are%203%20little%20dogs%20%3A%29%0A...maybe%20some%20day%201%20plus%202%20plus%2020%20could%20result%20in%203&debug=0) or [Test Suite](http://pyth.herokuapp.com/?code=J%3Az%22%5Cw%2B%221jdxDJhM.grhk0J&input=Take%20all%20first%20words%20for%20each%20letter...%20this%20is%20a%20test&test_suite=1&test_suite_input=Take%20all%20first%20words%20for%20each%20letter...%20this%20is%20a%20test%0ALook%20%5E_%5E%20....%20There%20are%203%20little%20dogs%20%3A%29%0A...maybe%20some%20day%201%20plus%202%20plus%2020%20could%20result%20in%203&debug=0)
`J:z"\w+"1` finds all the words in the input using the regex `\w+` and stores them in `J`.
`.grhk0J` groups the words by their lowercase first letter, `hM` takes the first from each group, `xDJ` sorts these words by their index in the input string, and `jd` puts spaces between them.
[Answer]
# Perl 6, 39 bytes
```
{.words.grep({!%.{.substr(0,1).lc}++})}
```
[Answer]
# C, ~~142~~ ~~132~~ 122 bytes
10 bytes lighter thanks to @tucuxi!
```
b[200],k;main(c){for(;~c;isalnum(c)|c==95?k&2?:(k|=!b[c|32]++?k&1?putchar(32):0,7:2),k&4?putchar(c):0:(k&=1))c=getchar();}
```
~~Prints a trailing space after the last output word.~~
[Answer]
# [MATL](https://esolangs.org/wiki/MATL), 23 bytes
```
'\w+'XXtck1Z)t!=XRa~)Zc
```
This borrows [Jakube's idea](https://codegolf.stackexchange.com/a/77275/36398) of using a regexp for removing unwanted characters and splitting at the same time.
Input is a string enclosed by single quotes.
[**Try it online!**](http://matl.tryitonline.net/#code=J1x3KydYWHRjazFaKXQhPVhSYX4pWmM&input=J1Rha2UgYWxsIGZpcnN0IHdvcmRzIGZvciBlYWNoIGxldHRlci4uLiB0aGlzIGlzIGEgdGVzdCc)
### Explanation
```
'\w+'XX  % find words that match this regexp. Gives a cell array
t        % duplicate
c        % convert into 2D char array, right-padded with spaces
k        % make lowercase
1Z)      % get first column (starting letter of each word)
t!=      % duplicate, transpose, test for equality: all combinations  
XR       % set diagonal and below to 0
a~       % true for columns that contain all zeros       
)        % use as a logical index (filter) of words to keep from the original cell array
Zc       % join those words by spaces
```
[Answer]
# Vim 57 keystrokes
```
:s/[^a-zA-Z_ ]//g<cr>A <cr>ylwv$:s/\%V\c<c-v><c-r>"\h* //eg<c-v><cr>@q<esc>0"qDk@q
```
Explanation:
```
:s/[^a-zA-Z_ ]//g                                 #Remove all invalid chars.
A <cr>                                            #Enter insert mode, and enter 
                                                  #a space and a newline at the end
ylwv$:s/\\c%V<c-v><c-r>"\h* //eg<c-v><cr>@q<esc>  #Enter all of this text on the 
                                                  #next line
0                                                 #Go to the beginning of the line
"qD                                               #Delete this line into register
                                                  #"q"
k@q                                               #Run "q" as a macro  
#Macro
ylw                                               #Yank a single letter
   v$                                             #Visual selection to end of line
     :s/                                          #Substitute regex
       \%V\c                                      #Only apply to the selection and 
                                                  #ignore case
            <c-v><c-r>"                           #Enter the yanked letter
                       \h*                        #All "Head of word" chars
                                                  #And a space
                           //                     #Replace with an empty string
                             eg                   #Continue the macro if not found
                                                  #Apply to all matches
                               <c-v><cr>          #Enter a <CR> literal
                                        @q<esc>   #Recursively call the macro
```
I'm really dissapointed by how long this one is. The "Invalid" chars (everything but `a-z`, `A-Z`, `_` and space) really threw me off. I'm sure there's a better way to do this:
```
:s/[^a-zA-Z_ ]//g
```
Since `\h` matches all of that expect for the space, but I can't figure out how to put the metachar in a range. If anyone has tips, I'd love to hear em.
[Answer]
# Julia, ~~165~~ ~~155~~ ~~151~~ ~~129~~ 102 bytes
```
g(s,d=[])=join(filter(i->i!=0,[(c=lcfirst(w)[1])∈d?0:(d=[d;c];w)for w=split(s,r"\W",keep=1<0)])," ")
```
This is a function that accepts a string and returns a string.
Ungolfed:
```
function g(s, d=[])
    # Split the string into an array on unwanted characters, then for
    # each word, if the first letter has been encountered, populate
    # this element of the array with 0, otherwise note the first letter
    # and use the word. This results in an array of words and zeros.
    x = [(c = lcfirst(w)[1]) ∈ d ? 0 : (d = [d; c]; w) for w = split(s, r"\W", keep=1<0)]
    # Remove the zeros, keeping only the words. Note that this works
    # even if the word is the string "0" since 0 != "0".
    z = filter(i -> i != 0, x)
    # Join into a string and return
    return join(z, " ")
end
```
Saved 53 bytes with help from Sp3000!
[Answer]
# Jelly, ~~32~~ 31 bytes
```
ØB;”_
e€¢¬œṗf€¢¹ÐfµZḢŒlQi@€$ịj⁶
```
[Try it online!](http://jelly.tryitonline.net/#code=w5hCO-KAnV8KZeKCrMKiwqzFk-G5l2bigqzCosK5w5BmwrVa4biixZJsUWlA4oKsJOG7i2rigbY&input=&args=IlRha2UgYWxsIGZpcnN0IHdvcmRzIGZvciBlYWNoIGxldHRlci4uLiB0aGlzIGlzIGEgdGVzdCI)
[Answer]
# **C# (LINQPAD) - 136 128 bytes**
```
var w=Util.ReadLine().Split(' ');string.Join(" ",w.Select(s=>w.First(f=>Regex.IsMatch(""+f[0],"(?i)"+s[0]))).Distinct()).Dump();
```
[Answer]
# [05AB1E](http://github.com/Adriandmen/05AB1E), 40 bytes
Code:
```
94L32+çJžj-DU-ð¡""Kvy¬Xsl©åï>iX®«Uy}\}ðý
```
[Try it online!](http://05ab1e.tryitonline.net/#code=OTRMMzIrw6dKxb5qLURVLcOwwqEiIkt2ecKsWHNswqnDpcOvPmlYwq7Cq1V5fVx9w7DDvQ&input=Li4ubWF5YmUgc29tZSBkYXkgMSBwbHVzIDIgcGx1cyAyMCBjb3VsZCByZXN1bHQgaW4gMw)
Explanation:
We first generate all characters which should be deleted from the input string using `94L32+ç` ([Try here](http://05ab1e.tryitonline.net/#code=OTRMMzIrw6c&input=)). We join this string using `J` and remove `[a-zA-Z0-9_]` which is stored in žj ([Try here](http://05ab1e.tryitonline.net/#code=xb5q&input=)). We remove all the characters that are in the second string from the first string, which will leave us:
```
!"#$%&'()*+,-./:;<=>?@[\]^`{|}~
```
That can also be tested [here](http://05ab1e.tryitonline.net/#code=OTRMMzIrw6dKxb5qLQ&input=). We `D`uplicate this and store in to `X` with the `U`-command. We then remove all the characters that are in this string from the input. We then split on whitespaces using `ð¡` and remove all empty strings (using `""K`). We now have [this](http://05ab1e.tryitonline.net/#code=OTRMMzIrw6dKxb5qLURVLcOwwqEiIks&input=Li4ubWF5YmUgc29tZSBkYXkgMSBwbHVzIDIgcGx1czopOikgMjAgY291bGQgcmVzdWx0IGluIDM).
This is the *clean* version of the input, which we will work with. We map over each element using `v`. This uses `y` as the string variable. We take the first character of the string using `¬` and push `X`, which contains a string with all *forbidden* characters (`!"#$%&'()*+,-./:;<=>?@[\]^`{|}~`). We check if the `l`owercase version of the first character, (which will also be `©`opied to the register), is in this string using `å`. Covered by this part: `ï>i`, if the first letter doesn't exist in the string of forbidden characters (`X`), we append this letter to the list of forbidden characters (done with `X®«U`) and we push `y` on top of the stack.
Finally, when the strings are filtered, we join the stack by spaces with `ðý`.
[Answer]
# **PHP**
Inspired by the use of regex in most of the answers, I originally tried to do this without using regex at all just to show off a neat variation, but the sticking point of not having clean strings as input ruined that idea. Sad.
**With function wrapper, 89 bytes**
```
function f($s){foreach(preg_split('/\W/',$s)as$w)$c[lcfirst($w)[0]]++?:$v.=" $w";echo$v;}
```
**Without function wrapper (needing $s pre-declared), 73 bytes**
```
foreach(preg_split('/\W/',$s)as$w)$c[lcfirst($w)[0]]++?:$v.=" $w";echo$v;
```
Explanation:
```
foreach(preg_split('/\W/',$s)as$w)$c[lcfirst($w)[0]]++?:$v.=" $w";echo$v;
        preg_split('/\w/',$s)                                             Break input on all non-word characters
foreach(                     as$w)                                        Loop through each 'word'
                                     lcfirst($w)[0]                       Take the first letter of the lowercase version of the word
                                  $c[              ]++?:                  Increment an array element with a key of that letter after checking if it's false-y (0)
                                                        $v.=" $w";        Add the word if the letter wasn't found (if the previous condition evaluated to false)
                                                                  echo$v; Print the new string to screen.
```
My only regret is that I couldn't find a faster way of checking/converting letter case.
[Answer]
# Python, 103 bytes
```
import re
lambda s,d=[]:[w for w in re.findall("\w+",s)if(d.append(w.lower()[0])or d[-1])not in d[:-1]]
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), 40 bytes
```
->s{s.scan(/\w+/).uniq{|x|x.ord|32}*' '}
```
[Try it online!](https://tio.run/##LU7BbsIwFLv3K3wDNhE2epu0HXfakds2ptC@thFpXnkvEVSUX18XpEm2LNmyZUmHcW5e5/WbXtVoZcNy83V@3KxMCu50nS7TxbDUU7m9PSywuM1Diorms@q4H77nd5LkbTY8J3HawQW0LC1xUrRWagpqip09Eqz3aJxoxDkP5goLyFYdPMVIYoxB7JwiwyKSxuKD@Yj9zx7mHu46krySWcK7GD2h5lbxsipy3NvxQFDus2tHPGPw@cH2X55QcfI1hDT5eD9Z/vIQHQed1@EP "Ruby – Try It Online")
`String#ord` returns the codepoint of the first character in a string and bitwise or with `32` maps uppercase codepoints to the lowercase ones and `95 (_)` to `127`, while keeping everything else the same.
[Answer]
## Lua, 172 Bytes
It ended up way longer that I wanted... 
```
t={}(...):gsub("[%w_]+",function(w)b=nil for i=1,#t
do b=t[i]:sub(1,1):lower()==w:sub(1,1):lower()and 1 or b
end t[#t+1]=not b and w or nil end)print(table.concat(t," "))
```
### Ungolfed
```
t={}                           -- initialise the accepted words list
(...):gsub("[%w_]+",function(w)-- iterate over each group of alphanumericals and underscores
  b=nil                        -- initialise b (boolean->do we have this letter or not)
  for i=1,#t                   -- iterate over t
  do
    b=t[i]:sub(1,1):lower()    -- compare the first char of t's i word
       ==w:sub(1,1):lower()    -- and the first char of the current word
           and 1               -- if they are equals, set b to 1
           or b                -- else, don't change it
  end
  t[#t+1]=not b and w or nil   -- insert w into t if b isn't set
end)
print(table.concat(t," "))     -- print the content of t separated by spaces
```
[Answer]
## Seriously, 43 bytes
```
6╙¬▀'_+,;)-@s`;0@Eùk`M┬i;╗;lrZ`i@╜í=`M@░' j
```
[Try it online!](http://seriously.tryitonline.net/#code=NuKVmcKs4paAJ18rLDspLUBzYDswQEVrYE3ilKxpYMO5YE074pWXO2xyWmBpQOKVnMOtPWBNQOKWkScgag&input=Ii4uLm1heWJlIHNvbWUgZGF5IDEgcGx1cyAyIHBsdXMgMjAgY291bGQgcmVzdWx0IGluIDMi)
The lack of regex capabilities made this much more difficult than it needed to be.
Explanation:
```
6╙¬▀'_+,;)-@s`;0@Eùk`M┬i;╗;lrZ`i@╜í=`M@░' j
6╙¬▀                                         push digits in base 62 (uppercase and lowercase letters and numbers)
    '_+                                      prepend underscore
       ,;)                                   push two copies of input, move one to bottom of stack
          -                                  get all characters in input that are not letters, numbers, or underscores
           @s                                split input on all occurrences of non-word characters
             `;0@Eùk`M                       for each word: push the first letter (lowercased)
                      ┬i                     transpose and flatten (TOS is list of first letters, then list of words)
                        ;╗                   push a copy of the first letters list to register 0
                          ;lrZ               zip the list of first letters with their positions in the list
                              `i@╜í=`M       for each first letter: push 1 if that is the first time the letter has been encountered (first index of the letter matches its own index) else 0
                                      @░     filter words (take words where corresponding element in the previous list is truthy)
                                        ' j  join on spaces
```
[Answer]
## Ruby 76 Bytes
```
s;f={};s.scan(/(([\w])[\w]*)/).map{|h,i|f[j=i.upcase]?nil:(f[j]=!p; h)}.compact.*' '
```
### Or with method definition 88 bytes
```
def m s;f={};(s.scan(/((\w)\w*)/).map{|h,i|f[j=i.upcase]?nil:(f[j]=1; h)}-[p]).*' ';end
```
Ungolfed and with unit test:
```
def m_long(s)
  #found  - Hash with already found initials
  f={}
  #h=hit, i=initial, j=i[0].downcase
  s.scan(/(([\w\d])[\w\d]*)/).map{|h,i| 
    f[j=i.upcase] ? nil : (f[j] = true; h)
  }.compact.join(' ')
end
#true == !p
#~ def m(s)
  #~ f={};s.scan(/(([\w\d])[\w\d]*)/).map{|h,i|f[j=i.upcase]?nil:(f[j]=!p; h)}.compact.join' '
#~ end
def m s;f={};s.scan(/(([\w\d])[\w\d]*)/).map{|h,i|f[j=i.upcase]?nil:(f[j]=!p; h)}.compact.join' ';end
#~ s = "Ferulas flourish in gorgeous gardens."
#~ p s.split
require 'minitest/autorun'
class FirstLetterTest < Minitest::Test
  def test_1
    assert_equal("Ferulas in gorgeous",m("Ferulas flourish in gorgeous gardens."))
    assert_equal("Ferulas in gorgeous",m_long("Ferulas flourish in gorgeous gardens."))
  end
  def test_2
    assert_equal("Take all first words each letter is",m("Take all first words for each letter... this is a test"))
    assert_equal("Take all first words each letter is",m_long("Take all first words for each letter... this is a test"))
  end
  def test_3
    assert_equal("Look _ There are 3 dogs",m("Look ^_^ .... There are 3 little dogs :)"))
    assert_equal("Look _ There are 3 dogs",m_long("Look ^_^ .... There are 3 little dogs :)"))
  end
  def test_4
    assert_equal("maybe some day 1 plus 2 could result in 3",m("...maybe some day 1 plus 2 plus 20 could result in 3"))
    assert_equal("maybe some day 1 plus 2 could result in 3",m_long("...maybe some day 1 plus 2 plus 20 could result in 3"))
  end
end
```
[Answer]
# grep and awk, 68 56 bytes
The script:
```
echo `grep -o '\w*'|awk '!x[tolower(substr($0,1,1))]++'`
```
Explanation:
* `grep -o` matches the legal words, printing each on its own line.
* `awk` takes the first letter of each line with `substr`, makes it lowercase, and then increments a hashtable entry with that key. If the value was unset before the increment, the line is printed.
* `echo ...` turns the lines back into words
I previously tried to create a solution without `awk`, using `uniq`, `sort`, `grep` and `bash` but fell just short. History in the edits.
Thanks to Dennis for some improvements I missed.
[Answer]
# [K (ngn/k)](https://codeberg.org/ngn/k), 55 bytes
```
{" "/w@.*'" "_=_*'w:" "\c(c:`c$&2!&48,27\3988544219)?x}
```
[Try it online!](https://ngn.bitbucket.io/k/#eJx1j0FPgzAUgO/8iidZtrEYdICRtTF68uRxt41BhQIN3WraEiCL/nYfmzEz6qFpk/d9X/NKcnTBveme/MUMH+lDuph1BF/bfJ6TLJ9Mg6tpFF8H99twFcd3URQsV95j/+44lhwnm+FDkxJ6mqmGzrOSCUl7OlDtJSOxcZ+5biUzUErVamFqEAeolK64ag1UTBf8YHyXfnMXYzcZA2vWcGBSQim0sdApXWBNaeAsr0Fya7n2fR9sLdA2wMByY7H4p3ghIXz+4UWpBnbpDvyxs665Rg9PCFJYKzkUqjJAPGye0PQHMw7PHbT3bHjlYNQeJTbAEt4krhl8XbeQq1YWoLlppR1XDbH5n/ObTRznE5UqiQw=)
* `(c:`c$&2!&48,27\3988544219)` a compressed version of `"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"`, stored in `c`
* `c(...)?x` replace all non-alphanumeric/underscore characters with spaces
* `w:" "\` split the converted input on spaces, storing in `w`
* `=_*'w` build a dictionary mapping the distinct (lowercased) leading characters to their words' position(s) within the input sentence
* `" "_` remove/ignore spaces
* `w@.*'` retrieve the first word beginning with each distinct character...
* `" "/` ...joining them together with spaces (to be implicitly returned)
[Answer]
# [Perl 5](https://www.perl.org/) `-n`, ~~44~~ 37 bytes
```
/./&&!$k{lc$&}++&&print$_,$"for/\w+/g
```
[Try it online!](https://tio.run/##DcPRCkAwFADQX7m0bmnYg7z4Bo8eRWJY1u6alQf5dZdTx@tga2ZVKsREHLedBT5SIvpgXBRjLtKVguovqTbmluiAYRyg/EG366Bh@ldgTYxWw0LbCU32ko@G3MmF@wA "Perl 5 – Try It Online")
[Answer]
# [Japt](https://github.com/ETHproductions/japt) v2.0a0 [`-S`](https://codegolf.meta.stackexchange.com/a/14339/), ~~19~~ 16 [bytes](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)
```
f/\w+/
üÈÎvÃmÎnU
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=2.0a0&flags=LVM&code=Zi9cdysvCvzIznbDbc5uVQ&input=IkZlcnVsYXMgZmxvdXJpc2ggaW4gZ29yZ2VvdXMgZ2FyZGVucy4i) or [run all test cases](https://petershaggynoble.github.io/Japt-Interpreter/?v=2.0a0&code=Zi9cdysvCvzIznbDbc5uVQ&footer=VnFT&input=WwoiRmVydWxhcyBmbG91cmlzaCBpbiBnb3JnZW91cyBnYXJkZW5zLiIKIlRha2UgYWxsIGZpcnN0IHdvcmRzIGZvciBlYWNoIGxldHRlci4uLiB0aGlzIGlzIGEgdGVzdCIKIkxvb2sgXl9eIC4uLi4gVGhlcmUgYXJlIDMgbGl0dGxlIGRvZ3MgOikiCiIuLi5tYXliZSBzb21lIGRheSAxIHBsdXMgMiBwbHVzIDIwIGNvdWxkIHJlc3VsdCBpbiAzIgpdLW1S)
```
f/\w+/\nüÈÎvÃmÎnU     :Implicit input of string U                  > "Ferulas flourish in gorgeous gardens."
f/\w+/                :Match /\w+/g                                > ["Ferulas","flourish","in","gorgeous","gardens"]
      \n              :Reassign to U
        ü             :Group and sort by
         È            :Passing each through the following function
          Î           :  First character                           >   ["F","f","i","g","g"]
           v          :  Lowercase                                 >   ["f","f","i","g","g"]
            Ã         :End function                                > [["Ferulas","flourish"],["gorgeous","gardens"],["in"]]
             m        :Map
              Î       :  First element                             > ["Ferulas","gorgeous","in"]
               nU     :Sort by index in U                          > ["Ferulas","in","gorgeous"]
                      :Implicit output joined with spaces          > "Ferulas in gorgeous"
```
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal) `S`, 16 bytes
```
kr‛ _+↔⇩⌈:vhÞU*'
```
[Try it Online!](https://lyxal.pythonanywhere.com?flags=S&code=kr%E2%80%9B%20_%2B%E2%86%94%E2%87%A9%E2%8C%88%3Avh%C3%9EU*%27&inputs=Take%20all%20first%20words%20for%20each%20letter...%20this%20is%20a%20test&header=&footer=)
Explanation:
```
kr‛ _+↔           # Remove any non A-Z,a-z,0-9,_, or space chars
       ⇩          # Lowercase
        ⌈         # Split on spaces
         :        # Duplicate
          vh      # Get the first letter of each
            ÞU    # Nub Sieve (Unique mask)
              *   # Multiply mask with list of words
               '  # Remove all empty strings
                  # 'S' flag - join top of stack with spaces and print
```
[Answer]
# Python 3.5, 138 bytes:
```
import re;lambda o,t=[]:''.join([y[0]for y in[(u+' ',t.append(u[0].lower()))for u in re.sub('\W+',' ',o).split()if u[0].lower()not in t]])
```
Basically, what's happening is..
1. Using a simple regular expression, the program replaces all the characters, except lowercase or uppercase letters, digits, or underscores in the given string with spaces, and then splits the string at those spaces.
2. Then, using list comprehension, create a list that iterates through all the words in the split string, and add the first letters of each word to list "t".
3. In the process, if the current word's first letter is NOT already in the list "t", then that word and a trailing space are added to the current list being created. Otherwise, the list continues on appending the first letters of each word to list "t".
4. Finally, when all words in the split have been iterated through, the words in the new list are joined into a string and returned.
[Answer]
**PHP 120bytes**
```
function a($s){foreach(preg_split('/\W/',$s)as$w)if(!$o[ucfirst($w[0])]){$o[ucfirst($w[0])]=$w;}return implode(" ",$o);}
```
This generates a bunch of warnings but that's fine.
[Answer]
# Javascript ES6, ~~108~~ 107 chars
### 107 chars, result string is trimmed
```
r=s=>s.split``.reverse().join``
f=s=>r(r(s).replace(/\b\w*(\w)\b(?=.*\1\b)/gi,'')).replace(/\W+/g,' ').trim()
```
Test:
```
["Take all first words for each letter... this is a test",
"Look ^_^ .... There are 3 little dogs :)",
"...maybe some day 1 plus 2 plus 20 could result in 3"
].map(f) + '' == [
"Take all first words each letter is",
"Look _ There are 3 dogs",
"maybe some day 1 plus 2 could result in 3"
]
```
[Answer]
# [Tcl](http://tcl.tk/), 150 bytes
```
proc F {s D\ {}} {lmap w [split $s] {regsub -all \[^\\w] $w "" f
if {![dict e $D [set k [string tol [string in $f 0]]]]} {dict se D $k $f}}
dict v $D}
```
[Try it online!](https://tio.run/##PVCxboQwDN35ilfE0qGo7W2dTzd1vA2OKgcGIsIFxU7RCfHt1DDUSuToxe/52VK7bZuCr3HBwjiXWNYVixvNhBkFT84KMr5hCdRxvOPNOIeyqMpyviGbkaZoE9tieSkaWwsI2Vl5JBg0SbCPDuLd/9s@kLV4v2lon4PChDOyQfF1TQ7kV0XW7TDBWJL0QiE6w2idj8Fyv6t0PnTkI6MzoaEHp0l6NQNh99fawILZh0Y5PoBM3cORCIU8zyG9ZegxEGJR4rf3A6qfCvn@fe0pqI7eE3R8cYTGd4yvVy0dzfNOYD8qaJ74wOTUwydqH12DQByd7PZOaaLzTVEYxWXf4Lr9AQ "Tcl – Try It Online")
[Answer]
# [Python 3](https://docs.python.org/3/), 131 bytes
```
lambda s:' '.join(sorted({w[0].lower():w for w in''.join(c*(c.isalnum()or c in'_ ')for c in s).split()[::-1]}.values(),key=s.find))
```
[Try it online!](https://tio.run/##VY9Ba8MwDIXv@xW6xR6baddbYNedduyta4sbK4lXxQqWvRDGfnvmjDIoSAih7z2exjn1HHZL@/qxkB0uzoLUFVTmk31QwjGhU9/TYXM0xBNGpesJWo4wgQ/VDWseVWO8WAp5ULocm/V4hkq3twVEGxnJJ6UPdf28Pf6YL0sZRemnK86vYlofnNbLGH1IqlXVG8ZMVqAlztFLv5p0HDvkLNDZ6DCIqbR@@Ffs7RXBEkHroySYODr5i4q26YEwJYzGGEi9FyhlIaGkO4t35iuczicwK7jvMRbH0jso0RMhOO4Ean0nKuhg5wuC8FAIO8MWRiopX25jAw1nchBRMqX1kV0xWH4B "Python 3 – Try It Online")
Solution without regex.
[Answer]
# [Husk](https://github.com/barbuz/Husk), 22 bytes
```
wÖ€₁¹m←ko_←₁
mf§|='_□w
```
[Try it online!](https://tio.run/##yygtzv7/v/zwtEdNax41NR7amfuobUJ2fjyQBHK5ctMOLa@xVY9/NG1h@f///0MSs1MVEnNyFNIyi4pLFMrzi1KKFdLyixRSE5MzFHJSS0pSi/SAQKEkI7NYAYgSFUpSi0sA "Husk – Try It Online")
The '\_' requirement is a bit annoying, otherwise a pretty interesting challenge.
## Explanation
```
function ₁: filter nonalphanumerics and split
mf§|='_□w 
        w split on spaces
mf        map and filter each letter in the words by:
       □  is it alphanumeric?
  §|      or:
    ='_   is it an underscore?
main function:
wÖ€₁¹m←ko_←₁
           ₁ format the input
       ko    key the words on:
         _←  first letter, lowercased
     m←      map each to first word
 Ö           order by:
  €₁¹        their index in the formatted input
w            join back with spaces
```
[Answer]
# Python, 93 bytes
```
import re
s=""
for w in re.findall("\w+",input()):
 if(a:=w[0].lower())not in s:s+=a;print(w)
```
]