Skip to content

add flatten() to flatten list#3676

Closed
mopp wants to merge 22 commits intovim:masterfrom
mopp:add_flatten
Closed

add flatten() to flatten list#3676
mopp wants to merge 22 commits intovim:masterfrom
mopp:add_flatten

Conversation

@mopp
Copy link

@mopp mopp commented Dec 8, 2018

This change adds a new small function flatten({list} [, {maxdepth}]) to flatten the given list to depth {maxdepth} like Ruby's flatten and Scala's flatten.

This function assists list processing combining list manipulation functions.
Here is example

" Collect paths from some patterns
echo flatten(map(['./xxx/*', './yyy/*'], 'glob(v:val, 0, 1)'))
" Split and filter strings
echo filter(flatten(map(zzz, 'split(v:val, ",")')), '!empty(v:val)')

The performance is good because it uses a loop instead of a recursive function call.
Some plugins (e.g., gina.vim, vim-snipmake) also need this function.
Currently these use library provided function (e.g., vital.vim, tlib_vim).

Thanks

@codecov-io
Copy link

codecov-io commented Dec 8, 2018

Codecov Report

Merging #3676 into master will decrease coverage by <.01%.
The diff coverage is 94.87%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3676      +/-   ##
==========================================
- Coverage   78.47%   78.47%   -0.01%     
==========================================
  Files         103      103              
  Lines      141874   141913      +39     
==========================================
+ Hits       111333   111362      +29     
- Misses      30541    30551      +10
Impacted Files Coverage Δ
src/evalfunc.c 87.69% <100%> (+0.03%) ⬆️
src/list.c 89.32% <91.3%> (+0.11%) ⬆️
src/gui.c 58.05% <0%> (-0.31%) ⬇️
src/sign.c 92.23% <0%> (-0.14%) ⬇️
src/gui_gtk_x11.c 48.23% <0%> (-0.1%) ⬇️
src/ex_cmds2.c 84.7% <0%> (-0.1%) ⬇️
src/window.c 83.39% <0%> (+0.03%) ⬆️
src/if_xcmdsrv.c 83.99% <0%> (+0.35%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b1443b4...af475dd. Read the comment docs.

@brammool
Copy link
Contributor

brammool commented Dec 8, 2018 via email

@mopp
Copy link
Author

mopp commented Dec 8, 2018

@brammool Thanks for your comment.

I would expect the most often used form is to flatten a nested list into a list of items.

Yes, I think so too.

The documentation about maxdepth is not enough or the name maxdepth is not suitable.
Some examples are here

It is called limit in case of vital.vim.

echo s:L.flatten([[['a']], [[['b']], 'c']], 2)
" => ['a', ['b'], 'c']

It is called level in case of Ruby's flatten.

a = [ 1, 2, [3, [4, 5] ] ]
a.flatten!(1) 
# => [1, 2, 3, [4, 5]]

The argument means "How deeply it makes flatten the list" usually.

I think it is better to follow them.
The name maxdepth may be required to change such as limit, level, expand_depth or etc.

item = list->lv_first;
while (item != NULL && !got_int)
{
line_breakcheck();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do a breakcheck? I think many list processing functions do not check for interrupts. But most importantly, it appears to put the list into an indeterminate state; if the function does return OK I would expect the list to be list flattened to maxdepth.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it appears to put the list into an indeterminate state; if the function does return OK

Yes, It should return FAIL if interrupted.
I will fix it.

it finds the file "tags.vim".

flatten({list} [, {maxdepth}]) *flatten()*
Flatten {list} to depth {maxdepth}. {maxdepth} means how
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be noted that flattening is done in-place, i.e., modifies the list (as other vim list functions)

:echo flatten([[[1], [2], [3]]], 1)
< [[1], [2], [3]]
*E964*
{maxdepth} must be positive number.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since zero is explicitly allowed (why?), this should say "must be a non-negative Number."

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This description is right because the given list is NOT modified when the maxdepth is 0.

It can deal with when a calculation result of maxdepth becomes 0.


flatten({list} [, {maxdepth}]) *flatten()*
Flatten {list} to depth {maxdepth}. {maxdepth} means how
deeply it makes flatten the list. the depth is 1 when
Copy link

@andymass andymass Jan 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not completely clear. Is it correct to say that the result is a List having depth N, i.e., a depth 1 List contains only Dict, Number, String, etc, whereas a depth 2 List may contain other lists (which do not contain lists themselves)?

Copy link
Author

@mopp mopp Jan 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry. My English is not good.

Is it correct to say that the result is a List having depth N

I already described at the #3676 (comment) .
Please check src/testdir/test_flatten.vim for more examples.

Thanks for your reviews 😄

@brammool brammool closed this in 077a1e6 Jun 8, 2020
@mopp mopp deleted the add_flatten branch June 9, 2020 01:56
@mopp
Copy link
Author

mopp commented Jun 9, 2020

Thank you for merging! 🎉

@brammool
Copy link
Contributor

brammool commented Jun 9, 2020 via email

@vim-ml
Copy link

vim-ml commented Jun 9, 2020 via email

shlomif pushed a commit to shlomif/neovim that referenced this pull request Jul 30, 2020
Problem:    Flattening a list with existing code is slow.
Solution:   Add flatten(). (Mopp, closes vim/vim#3676)
vim/vim@077a1e6
farisachugthai pushed a commit to farisachugthai/neovim that referenced this pull request Aug 4, 2020
Problem:    Flattening a list with existing code is slow.
Solution:   Add flatten(). (Mopp, closes vim/vim#3676)
vim/vim@077a1e6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants