2017-02-18 98 views
0

具有如下片段:如何在映射和拆分之後將地圖映射到特定元素?

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

回答

1

使用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

2

你可以使用 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

0

看來,我還可以用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