检查 Ticker 是否在另一个列表中,然后添加一个新键 [RamdaJS]
Checking if Ticker is in another list, then adding a new key [RamdaJS]
我正在尝试使用 Ramda 比较 2 个列表,找出 tickersList 中的哪些代码也在 portfolioTickers 中。如果投资组合列表中也有一个,则添加一个关键字 portfolio:true
。
示例数据:
tickers = [
{ ticker: aa },
{ ticker: bb },
{ ticker: cc }
]
portfolio = [
{ ticker: aa }
]
预期结果:
tickers = [
{ ticker: aa, portfolio: true },
{ ticker: bb },
{ ticker: cc }
]
听起来很简单,但到目前为止卡在这里:
const checkTicker = _.curry((ticker, portTicker) => {
if (ticker.ticker === portTicker.ticker) {
ticker.portfolio = true;
}
return ticker;
});
const matched = R.anyPass([checkTicker]);
const setPortfolioFlag = _.curry((portfolioTickers, ticker) => {
// const matched = R.filter(checkTicker(ticker), portfolioTickers);
// console.log('matched', matched)
const each = matched(R.forEach(checkTicker(ticker), portfolioTickers));
console.log('each', each)
return each;
});
const inPortfolioCheck = (tickersList) => {
const portfolioTickers = R.filter(TickersFactory.isTickerInPortfolio, tickersList);
const tickers = R.map(setPortfolioFlag(portfolioTickers), tickersList);
console.log('tickers', tickers)
};
const displayTickers = (tickers) => {
this.tickersList = tickers;
const checkedTickers = inPortfolioCheck(this.tickersList);
console.log('checkedTickers', checkedTickers)
};
现在 each
始终为真,所有这些逻辑的列表 returns 只是一个与我的 tickerList 长度相同的列表,但只是 true
'.
我一直 运行 关注的一个问题是我觉得我需要 运行 另一个 R.map
来进行检查,但是返回的地图的结果是 Portfolio代码,而不是原始列表。
工作代码,但有一个丑陋的 for 循环:
这显然有效,因为我使用的是 for 循环,但我试图删除所有面向对象的代码并替换为功能代码。
const setPortfolioFlag = _.curry((portfolioTickers, ticker) => {
for (var i=0; i<portfolioTickers.length; i++) {
if (portfolioTickers[i].ticker === ticker.ticker) {
ticker.portfolio = true;
}
}
return ticker;
});
const inPortfolioCheck = (tickersList) => {
const portfolioTickers = R.filter(TickersFactory.isTickerInPortfolio, tickersList);
return R.map(setPortfolioFlag(portfolioTickers), tickersList);
};
const displayTickers = (tickers) => {
this.tickersList = inPortfolioCheck(tickers);
console.log('this.tickersList', this.tickersList)
};
forLoop 的 LoDash 版本:
_.each(portfolio, (port) => {
if (port.ticker === ticker.ticker) {
ticker.portfolio = true;
}
});
所以您可能首先注意到的是预期结果 tickers
数组与输入 tickers
数组相同 "shape",这表明我们应该能够利用R.map
的表达式。知道了这一点,我们就可以专注于数组的各个元素必须发生的事情。
因此,对于每个代码对象,当在 portfolio
数组中找到时,我们想附加 portfolio: true
属性.
const updateTicker =
R.when(R.flip(R.contains)(portfolio), R.assoc('portfolio', true))
updateTicker({ ticker: 'aa' })
//=> {"portfolio": true, "ticker": "aa"}
updateTicker({ ticker: 'bb' })
//=> {"ticker": "bb"}
然后我们只需映射代码列表即可更新每个代码。
R.map(updateTicker, tickers)
//=> [{"portfolio": true, "ticker": "aa"}, {"ticker": "bb"}, {"ticker": "cc"}]
@scott-christopher 的回答一如既往地出色。但随后的评论让我认为它并没有完全涵盖您的用例。如果数据更复杂,并且 portfolio
和 tickers
中的项目可能具有不同的属性,那么 contains
就不够强大。因此,如果您的数据看起来更像这样:
const tickers = [
{ ticker: 'aa', size: 1 },
{ ticker: 'bb', size: 2 },
{ ticker: 'cc', size: 3 },
{ ticker: 'dd', size: 4 }
]
const portfolio = [
{ ticker: 'aa', id: 'abc' },
{ ticker: 'dd', id: 'xyz' }
]
那么这个版本可能会更好:
const updateTicker =
when(pipe(eqProps('ticker'), any(__, portfolio)), assoc('portfolio', true))
这个几乎没有积分的版本可能有点晦涩难懂。相当于这个:
const updateTicker =
when(
(ticker) => any(eqProps('ticker', ticker), portfolio),
assoc('portfolio', true)
)
还有,如果any(__, portfolio)
写法不清楚,相当于flip(any)(portfolio)
。
你可以在Ramda REPL上看到这个。
我正在尝试使用 Ramda 比较 2 个列表,找出 tickersList 中的哪些代码也在 portfolioTickers 中。如果投资组合列表中也有一个,则添加一个关键字 portfolio:true
。
示例数据:
tickers = [
{ ticker: aa },
{ ticker: bb },
{ ticker: cc }
]
portfolio = [
{ ticker: aa }
]
预期结果:
tickers = [
{ ticker: aa, portfolio: true },
{ ticker: bb },
{ ticker: cc }
]
听起来很简单,但到目前为止卡在这里:
const checkTicker = _.curry((ticker, portTicker) => {
if (ticker.ticker === portTicker.ticker) {
ticker.portfolio = true;
}
return ticker;
});
const matched = R.anyPass([checkTicker]);
const setPortfolioFlag = _.curry((portfolioTickers, ticker) => {
// const matched = R.filter(checkTicker(ticker), portfolioTickers);
// console.log('matched', matched)
const each = matched(R.forEach(checkTicker(ticker), portfolioTickers));
console.log('each', each)
return each;
});
const inPortfolioCheck = (tickersList) => {
const portfolioTickers = R.filter(TickersFactory.isTickerInPortfolio, tickersList);
const tickers = R.map(setPortfolioFlag(portfolioTickers), tickersList);
console.log('tickers', tickers)
};
const displayTickers = (tickers) => {
this.tickersList = tickers;
const checkedTickers = inPortfolioCheck(this.tickersList);
console.log('checkedTickers', checkedTickers)
};
现在 each
始终为真,所有这些逻辑的列表 returns 只是一个与我的 tickerList 长度相同的列表,但只是 true
'.
我一直 运行 关注的一个问题是我觉得我需要 运行 另一个 R.map
来进行检查,但是返回的地图的结果是 Portfolio代码,而不是原始列表。
工作代码,但有一个丑陋的 for 循环:
这显然有效,因为我使用的是 for 循环,但我试图删除所有面向对象的代码并替换为功能代码。
const setPortfolioFlag = _.curry((portfolioTickers, ticker) => {
for (var i=0; i<portfolioTickers.length; i++) {
if (portfolioTickers[i].ticker === ticker.ticker) {
ticker.portfolio = true;
}
}
return ticker;
});
const inPortfolioCheck = (tickersList) => {
const portfolioTickers = R.filter(TickersFactory.isTickerInPortfolio, tickersList);
return R.map(setPortfolioFlag(portfolioTickers), tickersList);
};
const displayTickers = (tickers) => {
this.tickersList = inPortfolioCheck(tickers);
console.log('this.tickersList', this.tickersList)
};
forLoop 的 LoDash 版本:
_.each(portfolio, (port) => {
if (port.ticker === ticker.ticker) {
ticker.portfolio = true;
}
});
所以您可能首先注意到的是预期结果 tickers
数组与输入 tickers
数组相同 "shape",这表明我们应该能够利用R.map
的表达式。知道了这一点,我们就可以专注于数组的各个元素必须发生的事情。
因此,对于每个代码对象,当在 portfolio
数组中找到时,我们想附加 portfolio: true
属性.
const updateTicker =
R.when(R.flip(R.contains)(portfolio), R.assoc('portfolio', true))
updateTicker({ ticker: 'aa' })
//=> {"portfolio": true, "ticker": "aa"}
updateTicker({ ticker: 'bb' })
//=> {"ticker": "bb"}
然后我们只需映射代码列表即可更新每个代码。
R.map(updateTicker, tickers)
//=> [{"portfolio": true, "ticker": "aa"}, {"ticker": "bb"}, {"ticker": "cc"}]
@scott-christopher 的回答一如既往地出色。但随后的评论让我认为它并没有完全涵盖您的用例。如果数据更复杂,并且 portfolio
和 tickers
中的项目可能具有不同的属性,那么 contains
就不够强大。因此,如果您的数据看起来更像这样:
const tickers = [
{ ticker: 'aa', size: 1 },
{ ticker: 'bb', size: 2 },
{ ticker: 'cc', size: 3 },
{ ticker: 'dd', size: 4 }
]
const portfolio = [
{ ticker: 'aa', id: 'abc' },
{ ticker: 'dd', id: 'xyz' }
]
那么这个版本可能会更好:
const updateTicker =
when(pipe(eqProps('ticker'), any(__, portfolio)), assoc('portfolio', true))
这个几乎没有积分的版本可能有点晦涩难懂。相当于这个:
const updateTicker =
when(
(ticker) => any(eqProps('ticker', ticker), portfolio),
assoc('portfolio', true)
)
还有,如果any(__, portfolio)
写法不清楚,相当于flip(any)(portfolio)
。
你可以在Ramda REPL上看到这个。