2
$\begingroup$

I have a list consisting of string signatures:

lis1 = {"ab","cd","ef","gh"}

I have another list:

lis2 = {"ab","efij","cde"}

I would like to find elements in lis2 that begin with known signatures in lis1 and then replace them with the corresponding signatures from lis1 to get:

res = {"ab", "ef", "cd"}

Hopefully, this is clearly stated. Please let me know if it isn't.

$\endgroup$
2
  • 1
    $\begingroup$ I would like to take elements in lis2 that begin with strings in lis1 and replace them with the corresponding element from lis1 what happens if lis1 has two such hits and not just one? $\endgroup$
    – Nasser
    Commented Aug 31, 2022 at 3:22
  • $\begingroup$ Thanks Nasser, good question - see my comments below. $\endgroup$
    – Suite401
    Commented Aug 31, 2022 at 4:03

2 Answers 2

2
$\begingroup$

There might be some edge cases to consider, but you might approach it as follows. Create a replacement rule for each element of lis1 (and keep a list of such rules):

replaceRules = (# ~~ ___ -> #) & /@ lis1

Now use this list of rules in StringReplace:

StringReplace[lis2, replaceRules]
$\endgroup$
2
  • $\begingroup$ Thanks for the response. This fails with lis1= {"abcd","defg", "defghij"} and lis2 = {"abcd", "defgxyz", "defghijxyz"}. It produces res = {"abcd","defg","defg"} instead of the desired res = {"abcd","defg","defghij"} $\endgroup$
    – Suite401
    Commented Aug 31, 2022 at 4:00
  • 1
    $\begingroup$ That’s one of the edge cases I mentioned. You probably need to sort lis1 by length (longest first). $\endgroup$
    – lericr
    Commented Aug 31, 2022 at 4:22
2
$\begingroup$

Using SubsetQ:

StringJoin @@@ 
 First /@ Select[Tuples[{Characters[lis1], Characters[lis2]}]
   , SubsetQ[Last@#, First@#] &]

{"ab", "cd", "ef"}

$\endgroup$
4
  • $\begingroup$ Also thanks! This approach with the same lis1 and lis2 in the comment above yields res = {"abcd","defg","defg","defghij"} instead of the desired res = {"abcd","defg","defghij"} $\endgroup$
    – Suite401
    Commented Aug 31, 2022 at 4:03
  • $\begingroup$ A Union command can fix it: StringJoin @@@ Union@(First /@ Select[Tuples[{Characters[lis1], Characters[lis2]}] , SubsetQ[Last@#, First@#] &]) $\endgroup$
    – Syed
    Commented Aug 31, 2022 at 4:12
  • $\begingroup$ Syed, thanks for your reply. I've found another edge where your solution does not provide the desired result. lis1 = {"defg", "defghij"} and lis2 = {"defghijxyz"}. Your solution yields {"defg", "defghij"}, where the desired solution would be just {"defghij"}. Grateful for any further thoughts. $\endgroup$
    – Suite401
    Commented Aug 31, 2022 at 15:30
  • $\begingroup$ You will need to start with the longest unique signature in lis1 if that is what you want. $\endgroup$
    – Syed
    Commented Aug 31, 2022 at 16:45

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.