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

问题描述:

具有如下片段:如何在映射和拆分之后将地图映射到特定元素?

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)))) 

使用until

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

group的默认比较a == b,不懒惰Untils工作。与group使用它,你需要通过一个对比的作品,这将是equal

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

替换'.map!(a => splitter(a,“:”)。 )''用'.map!(a => a.until(':'))'不知何故地弄乱我的结果:我得到未排序的数据(同时给予排序作为输入)。 – Patryk

+0

这可能是由于byLine的结果不稳定造成的,您可以尝试'a => a.idup.until(':')' – weltensturm

+0

相同:/完整代码段https://dpaste.dzfl.pl/d2cc511bd7cb – Patryk

你可以使用 std.algorithm.findSplitAfter

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

另一个选项结合find让你到:drop让你过去吧:(?任何想法,如果有类似除了front索引运算符)

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

这不是'findSplitAfter ... [1]''可是... findSplitBefore [0]'我一直在寻找对于。下拉不能按我想要的方式工作(它会在':'后面提取部分) – Patryk

+0

在你的问题中,“分割后的第一部分”和“查找:并将所有字符剪切到它”听起来就像你想要的部分之后':' – rcorre

+0

对不起,我可能使用了错误的措辞。我现在纠正了。 – Patryk

看来,我还可以用splitter.front

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

+1

'splitter'被懒惰地评估,不支持随机索引。你必须使用'drop'提升范围:'splitter(a,“:”)。drop(1).front' – rcorre