我有一个数组,我想通过将项目组合在一起来重新排序。 e.g:
[1, 1, 0, 1, 0, 1, 0] => [1, 1, 0, 1, 1, 0, 0]
OR
[1, 1, 0, 1, 0, 1, 0] => [[1, 1], [0], [1, 1], [0, 0]]
在此示例中,1s已与最大组大小为2个项目组合在一起。我不想将所有项目组合在一起 - 我只想配对值。
写我的函数的最佳方法是什么?降低?分类?我正在寻找一种使用函数式编程技术的干净解决方案,如果这样可以实现更好的抽象,最好采用多个步骤。我正在使用JavaScript,但如果逻辑清晰,我会接受任何语言作为答案。
一些背景:我有一个照片列表,我想重新排序列表,以便方形照片(在我的示例中名为1
)并排显示清单。
答案 0 :(得分:0)
编写我的函数的最佳方法是什么?
可能采用强制性但纯粹的方式 - 我们正在寻找O(n)
解决方案。
减少
好吧,基本上每个数组遍历都是某种reduce
。所以我们绝对可以使用它,但它并不一定能使代码在JavaScript中更具可读性。
排序
没有。我们没有对您的列表进行排序。
我正在寻找使用函数式编程技术的干净解决方案,如果这样可以实现更好的抽象,最好采用多个步骤。我使用JavaScript但如果逻辑清晰,我会接受任何语言作为答案。
好吧,在Haskell中它可能看起来像
import Control.Arrow
import Data.Either
groupRightPairs = groupNRights 2
groupNRights :: Int -> [Either a b] -> [Either a [b]]
groupNRights 0 xs = undefined
groupNRights n [] = []
groupNRights n (Left x:xs) = Left x : groupNRights n xs
groupNRights n xs = uncurry (:) $ first Right $ second (groupNRights n) $ spanNRights n xs
{- let (rs, rest) = spanNRights n xs
in (Right rs) : (groupNRights n rest) -}
where
spanNRights :: Int -> [Either a b] -> ([b], [Either a b])
spanNRights 0 xs = ([], xs)
spanNRights n [] = ([], [])
spanNRights n (Left x:xs) = second ((Left x):) (spanNRights n xs)
spanNRights n (Right x:xs) = first (x:) (spanNRights (n-1) xs)
然而,JavaScript没有缺点列表,所以当你可以将它转换为JS时,它看起来不再那么好了(虽然没有类型限制它会变得更简单)。相反,你宁愿这样做:
function getOnePairs(arr) {
return getOneGroups(arr, n);
}
function getOneGroups(arr, n) {
var result = [],
group = [];
for (var i=0; i<arr.length; i++) {
if (arr[i] != 1) {
result.push(arr[i]);
} else {
if (group.length >= n)
result.push(group = []);
group.push(arr[i]); // this mutation is not very functional
}
}
return result;
}