19
\$\begingroup\$

Given two strings: a string s and an alphabet a, implement string projection in the shortest code possible.

String projection returns a string o that contains the characters in s that are in a. The order of the characters in o must match the order of characters in s. So if s = "abcd" and a = "12da34", o = "ad", since only "ad" is shared between s and a.

You will need to handle when a is empty (outputs empty string, since no character in s can match empty string).

Test Cases

"string", "alphabet" => "output"
-------------------------------
"abcd", "12da34" => "ad"
"hello, world!", "aeiou" => "eoo"
"hello, world!", "abcdefghijklmnopqrstuvwxyz" => "helloworld"
"Hello, World!", "abcdefghijklmnopqrstuvwxyz" => "elloorld" (case sensitivity)
"Hello, World!", "abcdef" => "ed"
"Hello, World!", "!,. \n\t" => ", !" (newline, tab)
"172843905", "abc123" => "123"
"fizzbuzz", "" => ""
"fizzbuzz", "fizzbuzz" => "fizzbuzz"
"", "fizzbuzz" => ""
"fizzbuzz", "zzzzz" => "zzzz"
"", "" => "" (two empty strings)

Winning Criteria

This is , so shortest code wins!

asked Aug 7, 2022 at 16:41
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Surprised by how many golflangs have a builtin or two for this task \$\endgroup\$ Commented Aug 10, 2022 at 8:51
  • 1
    \$\begingroup\$ prolog builtin is intersection/3 \$\endgroup\$ Commented Sep 7, 2022 at 14:16

47 Answers 47

1
2
1
\$\begingroup\$

Haskell + hgl, 5 bytes

fl<fe

Attempt This Online!

Pretty straight forward. fl filters fe checks if something is an element. Ends up being the same as the vanilla Haskell answer.

Reflection

This is a very simple task so there's not a lot to be said but:

  • I'm not sure why e was given the shorter name than fe. fe is almost certainly the more useful of the two and probably they should be swapped.
  • Since this is such a simple task, hgl should probably follow the lead of the golfing langs and make this a builtin.
  • There are a bunch of builtins that are similar to this task like nx, but the descriptions were not the clearest.
answered Aug 9, 2022 at 8:19
\$\endgroup\$
1
\$\begingroup\$

Red, 48 bytes

func[a b][foreach x a[if find/case b x[prin x]]]

Try it online!

answered Aug 12, 2022 at 10:37
\$\endgroup\$
1
\$\begingroup\$

GolfScript, 15 bytes

~`{1$?)\''if}+%

Try it online!

answered Aug 12, 2022 at 13:58
\$\endgroup\$
1
\$\begingroup\$

Scala, 8 bytes

_.filter

Try it online!

This is an expression of type String => Set[Char] => String. It uses the fact that a Set[T] is a function T => Boolean, which is used the predicate here.

answered Aug 14, 2022 at 9:07
\$\endgroup\$
1
\$\begingroup\$

brev, 34 bytes

(as-list(c lset-intersection eq?))

Brev imports all of srfi-1 by default. The partial application combinator c applies eq? and then the as-list combinator makes the list operator work on (and return) strings (and other stuff) as if they were lists.

answered Aug 21, 2022 at 20:37
\$\endgroup\$
1
\$\begingroup\$

Dart (2.18.4), 55 bytes

f(s,a)=>s.split('').where((e)=>!!a.contains(e)).join();
answered Aug 8, 2022 at 11:02
\$\endgroup\$
1
\$\begingroup\$

Go, 104 bytes

import."strings"
func f(s,a string)(o string){for i:=range s{r:=s[i:i+1]
if Contains(a,r){o+=r}}
return}

Attempt This Online!

answered Dec 24, 2022 at 17:36
\$\endgroup\$
1
\$\begingroup\$

Japt, (削除) 3 (削除ここまで) 2 bytes

fV

Try it

Takes input strings as character arrays

3 bytes w/ strings for input:

oV1

Try it

oV1
o : only keep characters in first input and
 V : second input
 1 : case sensitive
answered Dec 24, 2022 at 15:43
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Welcome to Japt :) \$\endgroup\$ Commented Dec 24, 2022 at 20:03
  • \$\begingroup\$ You could do this in 2 by taking input as arrays of characters. \$\endgroup\$ Commented Dec 24, 2022 at 20:12
  • \$\begingroup\$ @Shaggy Thanks, forgot you are allowed to do that lol. This is my first Japt answer I've posted, but I've been messing around with it for a week or two, since I mostly just write JS answers \$\endgroup\$ Commented Dec 26, 2022 at 0:27
1
\$\begingroup\$

POSIX Shell + Utilities, 26 bytes

printf %s "1ドル"|tr -cd "2ドル"

Fundamentally, the operation is tr -cd alphabet, all of 11 bytes on the right side of the pipe; more than half of the space is spent on turning the specified calling convention into data in a file. Unclear if taking the input from the standard input stream is allowed.

The tr alphabet accepts \n and \t for line and tab, but the spec does comment that it means a literal one, I think? Either work, but.

Transcript of test cases:

$ cat c.sh; echo; wc -c c.sh
printf %s "1ドル"|tr -cd "2ドル"
26 c.sh
$ ./c.sh "abcd" "12da34"; echo
ad
$ ./c.sh "hello, world!" "aeiou"; echo
eoo
$ ./c.sh "hello, world!" "abcdefghijklmnopqrstuvwxyz"; echo
helloworld
$ ./c.sh "Hello, World!" "abcdefghijklmnopqrstuvwxyz"; echo
elloorld
$ ./c.sh "Hello, World!" "abcdef"; echo
ed
$ ./c.sh "Hello, World!" "!,.
 "; echo
, !
$ ./c.sh "172843905" "abc123"; echo
123
$ ./c.sh "fizzbuzz" ""; echo
$ ./c.sh "fizzbuzz" "fizzbuzz"; echo
fizzbuzz
$ ./c.sh "" "fizzbuzz"; echo
$ ./c.sh "fizzbuzz" "zzzzz"; echo
zzzz
$ ./c.sh "" ""
```
answered Dec 26, 2022 at 1:49
\$\endgroup\$
1
\$\begingroup\$

Thunno 2, 2 bytes

Ƈị

Try it online!

I/O as a list of characters.

Explanation

 # Implicit input
 ị # Keep only the characters of the first input
Ƈ # which are contained in the second input
 # Implicit output
answered Jul 22, 2023 at 16:48
\$\endgroup\$
1
\$\begingroup\$

Racket, 79 bytes

(define(p s a)(apply string(for/list([c s]#:when(string-contains? a(~a c)))c)))

Try it online!


Explanation

We create a function called p that receives two inputs s and a which are the string to match and the string of what to match respectively. We loop through the characters of s and see whether each character appears in a. When a character does appear, we accumulate that character into a list. Once the list is obtained, we convert the characters to a single string.

(define (projection s a)
 (apply string
 (for/list ([char s] #:when (string-contains? a (~a char)))
 char)))

Conclusion

Have an amazing weekend!

answered Jul 22, 2023 at 17:34
\$\endgroup\$
0
\$\begingroup\$

J, 5 4 bytes

e.#[

Try it online!

-1 byte thanks to seeing the word "filter" in Jonathan's Jelly answer

Filter by # element of e..

answered Aug 7, 2022 at 17:26
\$\endgroup\$
0
\$\begingroup\$

JavaScript (Node.js), 41 bytes

Presently invalid as does not handle alphabets containing - or ]. (as pointed out by Deadcode)

s=>a=>s.replace(RegExp(`[^${a}]`,'g'),'')

Attempt This Online!

answered Aug 8, 2022 at 1:29
\$\endgroup\$
3
  • \$\begingroup\$ This fails when given an a string containing - or ]. There's a really neat way around this in Perl, but I don't there is in JavaScript. \$\endgroup\$ Commented Aug 8, 2022 at 2:35
  • \$\begingroup\$ @Deadcode, Thanks for pointing this out! I don't think there's an easy way around that. If I think of something I'll update the answer. \$\endgroup\$ Commented Aug 8, 2022 at 2:38
  • \$\begingroup\$ @MatthewJensen you could change a to a.replace(/-|]|\\/g,"\\$&") inside the template literal while you're trying to think of a better solution \$\endgroup\$ Commented Aug 8, 2022 at 16:02
0
\$\begingroup\$

Burlesque, 2 bytes

IN

Try it online!

Builtin intersection.

answered Aug 8, 2022 at 10:30
\$\endgroup\$
0
\$\begingroup\$

awk 24-bytes solution — it's not all that short but it gets the job done*

— *some bugs still exist

echo 'abcd 12da34' | 
awk 'gsub("[^"$NF"]",_,$--NF)' 
ad
echo 'hello, world!=naeiou' | 
awk 'gsub("[^"$NF"]",_,$--NF)' FS== | 
awk NF=NF FS= OFS='\n' | awk '!__[$_]++' ORS= 
  • or
awk 'gsub("[^"$!_ "]",_,$NF)
 gsub("[^"$NF"]",_,$!_)($_=$NF)' FS==
eo
answered Dec 25, 2022 at 9:17
\$\endgroup\$
2
  • \$\begingroup\$ Which code block is your solution? Put that at the top so it's clear that it's your solution. \$\endgroup\$ Commented Dec 25, 2022 at 18:17
  • \$\begingroup\$ @bigyihsuan : i don't really have one solution just yet, since those approaches always had minor gaps in the set of test cases, and i'm still trying to come up with an awk solution that is all encompassing without using loops, which would be my last resort \$\endgroup\$ Commented Dec 25, 2022 at 21:16
0
\$\begingroup\$

Arturo, 38 bytes

$[s,a]->join select split s'c[in? c a]

Try it

answered Jan 15, 2023 at 3:36
\$\endgroup\$
0
\$\begingroup\$

Uiua, 3 bytes

▽∊,

Try it!

▽∊,
 , # over
 ∊ # member
▽ # keep
answered Oct 19, 2023 at 17:50
\$\endgroup\$
1
2

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.