Erlang:展平字符串列表

发布于 2024-09-03 04:24:52 字数 482 浏览 2 评论 0原文

我有一个这样的列表:

[["str1","str2"],["str3","str4"],["str5","str6"]]

我需要将其转换为

["str1", "str2", "str3", "str4", "str5", "str6"]

How do I do this?

问题是我正在处理字符串列表,所以当我这样做时,

lists:flatten([["str1","str2"],["str3","str4"],["str5","str6"]])

我得到了

"str1str2str3str4str5str6"

但是,如果原始列表的元素只是原子,那么 lists:flatten 就会给我我需要的东西。如何使用字符串实现相同的效果?

I have a list like this:

[["str1","str2"],["str3","str4"],["str5","str6"]]

And I need to convert it to

["str1", "str2", "str3", "str4", "str5", "str6"]

How do I do this?

The problem is that I'm dealing with lists of strings, so when I do

lists:flatten([["str1","str2"],["str3","str4"],["str5","str6"]])

I get

"str1str2str3str4str5str6"

However, if the elements of the original list where just atoms, then lists:flatten would have given me what I needed. How do I achieve the same with strings?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

苍景流年 2024-09-10 04:24:52

list:append 正是您所需要的:

1> lists:append([["str1","str2"],["str3","str4"],["str5","str6"]]).
["str1","str2","str3","str4","str5","str6"]

(lists:concat 做了正确的事情,但也威胁要进行一些类型转换。)

lists:append does exactly what you need:

1> lists:append([["str1","str2"],["str3","str4"],["str5","str6"]]).
["str1","str2","str3","str4","str5","str6"]

(lists:concat does the right thing, but threatens to do some type conversion too.)

明天过后 2024-09-10 04:24:52

如果您的列表始终是“字符串列表的列表”,那么您可以简单地使用 foldl 运算符,例如:

Flat = list:foldl(fun(X, Acc) -> X ++ Acc end, [], List)

如果您的列表嵌套可以是任意深度,我宁愿建议让 erlang 知道你的字符串不仅仅是字符列表,使用如下编码:

[[{string, "str1"},{string, "str2"}],
 [{string, "str3"}, {string, "str4"}],
 [{string, "str5"},{string, "str6"}]]

这样, list:flatten 将做正确的事情,并给出:

[{string, "str1"},{string, "str2"},
 {string, "str3"}, {string, "str4"},
 {string, "str5"},{string, "str6"}]

如果需要,你可以将其转换回原始值使用 foldl 的字符串列表。
如果您的字符串的处理方式与单纯的字符列表不同,那么它们可能应该成为真正的数据结构,请参阅此 博客条目 有关此问题的有趣讨论。

If your list is always a "list of list of string", then you can simply use the foldl operator, with something like:

Flat = list:foldl(fun(X, Acc) -> X ++ Acc end, [], List)

In the case your list nesting can be of arbitrary depth, I would rather suggest to let erlang know your strings are not mere character lists, using an encoding such as:

[[{string, "str1"},{string, "str2"}],
 [{string, "str3"}, {string, "str4"}],
 [{string, "str5"},{string, "str6"}]]

This way, list:flatten will do the right thing, and give:

[{string, "str1"},{string, "str2"},
 {string, "str3"}, {string, "str4"},
 {string, "str5"},{string, "str6"}]

which you can convert back if needed to a raw list of strings using foldl.
If your strings are to be handled differently from mere character lists, then they probably deserve to be a real data structure, see this blog entry for an interesting discussion on this matter.

我不会写诗 2024-09-10 04:24:52

列表:concat/1 有效...

lists:concat/1 works...

春花秋月 2024-09-10 04:24:52

list:flatten 不适合你的原因是 Erlang 中的字符串只是小整数的列表。我们可以使用一个函数来处理这个问题,如果列表只是一个字符串,该函数会停止在嵌套列表中向下递归。

对于任意嵌套的字符串列表,您可以使用以下函数:

slab([]) ->
    [];
slab([F|R]) ->
    case io_lib:char_list(F) of
        true -> [F|slab(R)];
        false -> slab(F) ++ slab(R)
    end.

它使用 io_lib:char_list() 来决定嵌套递归是否足够深。

操作示例:

1> slab([[["foo", "bar"], "baz", [[[["foobar"]]]], "froboz", "the end"]]).
["foo","bar","baz","foobar","froboz","the end"]
2>

一个小改进,可以使用混合嵌套列表:

slab([]) ->
    [];
slab([F|R]) when is_list(F) ->
    case io_lib:char_list(F) of
        true -> [F|slab(R)];
        false -> slab(F) ++ slab(R)
    end;
slab([F|R]) ->
    [F|slab(R)].

其行为就像列表:展平,只不过它处理字符串就好像它们不是列表一样:

1> slab([[["foo", "bar"], "baz", [[[["foobar", atom]],[a,b,c]]], 2, "froboz", "the end"]]).
["foo","bar","baz","foobar",atom,a,b,c,2,"froboz","the end"]

The reason lists:flatten doesn't work for you is that strings in Erlang are just lists of small integers. We can handle this with a function that stops recursing down in a nested list if the list is just a string.

For arbitrarily nested list of strings you can use the following function:

slab([]) ->
    [];
slab([F|R]) ->
    case io_lib:char_list(F) of
        true -> [F|slab(R)];
        false -> slab(F) ++ slab(R)
    end.

It uses io_lib:char_list() to decide if the nesting recursion was deep enough.

Exampe of operation:

1> slab([[["foo", "bar"], "baz", [[[["foobar"]]]], "froboz", "the end"]]).
["foo","bar","baz","foobar","froboz","the end"]
2>

A small improvement that would make it possible to use mixed nested lists:

slab([]) ->
    [];
slab([F|R]) when is_list(F) ->
    case io_lib:char_list(F) of
        true -> [F|slab(R)];
        false -> slab(F) ++ slab(R)
    end;
slab([F|R]) ->
    [F|slab(R)].

This behaves just like lists:flatten except that it handles string as if they would be no lists:

1> slab([[["foo", "bar"], "baz", [[[["foobar", atom]],[a,b,c]]], 2, "froboz", "the end"]]).
["foo","bar","baz","foobar",atom,a,b,c,2,"froboz","the end"]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文