如何在地图和拆分后将地图带到特定元素?

时间:2017-02-18 12:29:31

标签: split functional-programming d

拥有以下代码段:

import std.algorithm;
import std.array : split;
import std.stdio;
import std.file;
import std.range;

void main(string[] args)
{
    string filename = "file.log";
    string term = "action";
    auto results = File(filename, "r")
                    .byLine
                    .filter!(a => canFind(a, term))
                    .map!(a => splitter(a, ":"));
                    // now how to take only first part of split? up to first ':'?

    foreach (line; results)
        writeln(line);
}

我只对分割操作后的第一部分感兴趣(或者其他一些可能更有效的操作 - 只需先查找:并提取所有字符)。

我尝试过类似的事情:

.map!(a => a[0])
拆分后

但我收到了错误

main.d(37): Error: no [] operator overload for type Result
/usr/include/dmd/phobos/std/algorithm/iteration.d(488):        instantiated from here: MapResult!(__lambda4, MapResult!(__lambda3, FilterResult!(__lambda2, ByLine!(char, char))))
main.d(37):        instantiated from here: map!(MapResult!(__lambda3, FilterResult!(__lambda2, ByLine!(char, char))))

3 个答案:

答案 0 :(得分:2)

你可以使用 std.algorithm.findSplitAfter

    auto results = File(filename, "r")
                    .byLine
                    .filter!(a => canFind(a, term))
                    .map!(a => a.findSplitAfter(":")[1]);

另一个选项结合了find,可以让您转到:drop,让您通过它:

auto results = File(filename, "r")
                .byLine
                .filter!(a => canFind(a, term))
                .map!(a => a.find(":").drop(1));

答案 1 :(得分:1)

使用until

.map!(a => a.until(':'));

group的默认比较是a == b,它不适用于懒惰的直播。要将其与group一起使用,您需要传递一个有效的比较,即equal

    .map!(a => a.until(':'))
    .group!equal
    ...

答案 2 :(得分:0)

似乎我也可以使用splitter.front

auto results = File(filename, "r")
                .byLine
                .filter!(a => canFind(a, term))
                .map!(a => splitter(a, ":").front);

(除了front之外还有像索引操作符这样的东西吗?)