I have two different lists of words and I want to make sure that they have no mutual duplicates. In other words, none of the words in list A can be in list B and vice versa. They must be mutually exclusive word lists.

Both lists are guaranteed to be sorted alphabetically.

How can I do this?

  • 1
    Are you talking about a vimscript list or a bunch of words in a file? If the latter, what format are they in? (One word per line? Separated by commas?)
    – DJMcMayhem
    Jan 24 '19 at 16:08
  • Are these lists of words contained in separate files? If so, see e.g. stackoverflow.com/questions/15470260/…. For me this question as it stands is off-topic.
    – Hotschke
    Jan 24 '19 at 16:13

The easiest solution in my mind is to use comm utility.

List A:

comm -2 -3 a.txt b.txt > a.txt

List B:

comm -1 -3 a.txt b.txt > b.txt

You can do this inside of Vim with the filter command, :!. e.g. :%!comm -2 -3 % b.txt

For more help see man comm and :h :range!


I answer in the case you wish to test the intersection between two |List| expressions, and not comparing text. In that later case others have already provide good answers.

Linear O(N) algorithms won't be efficient once implemented in vimscript as they would require using :for which has terrible performances. Functional O(N²) implementations are likely to be the fastest with current versions of Vim.

For instance, in that case I'd use the following function from my vim script library

function! lh#list#intersect(list1, list2) abort
  let result = copy(a:list1)
  call filter(result, 'index(a:list2, v:val) >= 0')
  return result
  • I like that you addressed the vimscript possibility, but could you provide some references for the comments on performance? Im curious to read more about it
    – D. Ben Knoble
    Jan 25 '19 at 22:25
  • 1
    @D.BenKnoble. Unfortunately I don't have numbers to provide, as I haven't keep them. I did experiments with lists of up to tens of thousands elements. Often I've observed a clear win for functional API (map() and filter()) over traditional iterative algorithms (:for, :while). Everything started with the need to process and analyse a lot of tags. In the end, I've rewritten several functions from my autoload/lh/list.vim file, just to speed up what could be. Note that I don't exclude that with greater numbers of elements, lower complexity is likely to win. Jan 25 '19 at 23:44

A “visual” solution would be to arrange two windows, each with one of the two buffers you want to view (e.g. vim a b then :vs | next).

Then do :windo diffthis to turn on the diff mode.

Untested, but you might be able to vimdiff a b.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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