2017-08-18 30 views
0

我想写一个Observable来从类似CSV文件的东西中返回对象。我的问题是我想使用该文件的标题,将其用作Observer的下一个元素的属性名称。举例来说,如果我有这样的CSV:如何从observable获取第一个元素并返回该流的其余部分的可观察值?

symbol;word 
1;one 
2;two 
3;three 

我希望这种情况发生:

getObjects().subscribe(o => console.log(o)); 

// should log this: 
{ symbol: '1', word: 'one' } 
{ symbol: '2', word: 'two' } 
{ symbol: '3', word: 'three' } 

我设法与此代码做到这一点:

const Rx = require('rxjs/Rx'); 
const _zipObject = require('lodash/zipObject'); 

const getObjects =() => { 
    const observable = Rx.Observable.of(
     ['symbol', 'word'], 
     ['1', 'one'], 
     ['2', 'two'], 
     ['3', 'three'] 
    ).share(); 

    let header; 

    return Rx.Observable.concat(
     observable.first().do(line => header = line).filter(() => false), 
     observable.skip(1).map(line => _zipObject(header, line)) 
    ); 
}; 

getObjects().subscribe(o => console.log(o)); 

它的工作原理,但没有按感觉不错。我还想过使用过滤器来过滤第一个元素并设置头文件,但它不会感觉好多了,并且会为每个元素调用过滤器回调函数。

回答

1

您可以使用combineLatest来获得,同时头和日期,避免从父范围访问它:

const Rx = require('rxjs/Rx'); 
const Observable = Rx.Observable; 

const getObjects =() => { 
    const observable = Observable.of(
     ['symbol', 'word'], 
     ['1', 'one'], 
     ['2', 'two'], 
     ['3', 'three'] 
    ).share(); 

    const header$ = observable.take(1); 
    const data$ = observable.skip(1); 

    return Observable.combineLatest(header$, data$, (headers, line) => { 
     const result = {}; 
     headers.forEach((header, i) => { 
      result[header] = line[i]; 
     }); 

     return result; 
    }); 
}; 

getObjects().subscribe(o => console.log(o)); 

此打印:

{ symbol: '1', word: 'one' } 
{ symbol: '2', word: 'two' } 
{ symbol: '3', word: 'three' } 
+0

太好了!谢谢!! –

相关问题