我有一个包含一些数据的数组,即
const data = [[ , '+', ],
['+', , '+'],
[ , , '+']]
我想获得每个元素的[x,y]坐标为'+':
const expected = [[1, 0], [0, 1], [2, 1], [2, 2]]
我怎么能在Ramda那样做?
我淘汰了一些有效的代码:
const getHorizontalPosition = R.map(R.addIndex(R.reduce)
( (xs, el, idx) => R.equals('+', el) ? R.append(idx, xs) : xs, [] ))
const combineWithVerticalPosition = R.addIndex(R.chain)
( (xs, y) => R.map( (x) => [x, y] )(xs) )
pipe(getHorizontalPosition,
combineWithVerticalPosition)(data)
但是,正如你所看到的那样,它很丑陋而且不太可读。我怎样才能更优雅地做到这一点?
答案 0 :(得分:3)
正如您可能已经注意到的那样,Ramda对索引处理没有太大作用。我无法想出一个特别好的解决方案。
这样的东西会起作用,但在评论中提到的两个减速器似乎不那么优雅了:
pipe(addIndex(map)((xs, i) => pipe(
map(equals('+')),
addIndex(map)((x, j) => x && [i, j]),
reject(equals(false))
)(xs)), unnest)(data)
您可以在 Ramda REPL 。
上看到这一点答案 1 :(得分:1)
ES6的优雅之处在于。来到ES6后不需要Ramda。
const result= [];
data.forEach((row, i) =>
row.forEach((item, j) => item === '+' && result.push([i, j]))
)
另一种方式(没有突变+不使用var
,const
或let
):
[].concat(...data.map((row, i) => row.map((item, j) => item === '+' ? [
[i, j]
] : [])
.filter(coord => coord.length)
)
)
const data = [[ , '+', ],
['+', , '+'],
[ , , '+']]
const result= [];
data.forEach((row, i) =>
row.forEach((item, j) => item === '+' && result.push([i, j]))
)
console.log(
result
)

答案 2 :(得分:1)
这是另外一种方法
const hasPlus = item => item == '+'
const notNull = item => item != null
const joinResults = (prev,next) => prev.concat(next);
const results = Array.from(data, (value2d, y) => {
let indexOrNull = Array.from(value2d, (value1d, x) => hasPlus(value1d) ? x : null);
let indices = filter(notNull, indexOrNull);
let indexed = map(x => [x, y] , indices);
return indexed;
})
reduce(joinResults, [], results);
答案 3 :(得分:0)
const mapIndexed = R.addIndex(R.map)
const getIndexes = (xss) =>
R.unnest(mapIndexed((xs, i) => mapIndexed((x, j) => [i, j], xs), xss))
const data = [[ , '+', ],
['+', , '+'],
[ , , '+']]
const output =
R.filter(R.pathEq(R.__, '+', data), getIndexes(data))
console.log(output)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>