与javascript中的Array.reduce()相反

时间:2014-03-25 02:05:02

标签: javascript arrays loops

Array.reduce()接受一个数组,并将数组中的元素与累加器组合,直到消耗掉所有元素。

是否有一个函数(通常称为"展开"在其他语言中)以一个值开头并一直生成元素,直到生成一个完整的数组(累加器耗尽)?

我试图将此作为在任意碱基之间转换的一部分。我拥有的代码如下,但我想消除原始循环。

var dstAlphabet = "0123456789ABCDEFGH";
var dstBase = dstAlphabet.length;
var wet = BigInteger(100308923948716816384684613592839);
var digits_reversed = [];
while (wet.isPositive())
{
  // var digitVal = wet % dstBase
  var divRem = wet.divRem(dstBase); // [result of division, remainder]
  wet = divRem[0];
  digits_reversed.push(dstAlphabet.charAt(divRem[1].toJSValue()));
}

return digits_reversed.reverse().join("");

3 个答案:

答案 0 :(得分:3)

JavaScript中Array#reduce的反义词是Array.from(或者spread syntax)。您可以将其与任何iterable对象一起使用以生成数组:

from django.db.models import Case, When

model.objects.filter(a=Case(When(x=None, then='b'), default='c'))

可以通过调用generator function创建迭代器:

array = Array.from(iterator); // same as array = [...iterator];

生成器函数使用特殊关键字yield返回其结果(或使用yield*返回另一个可迭代项的所有结果)。一旦返回,它们就会耗尽:

iterator = generate(params);

或者,您也可以自己实现迭代器而无需生成器功能:

function* convertBase(wet, alphabet) {
    const base = BigInt(alphabet.length);
    wet = BigInt(wet);
    while (wet > 0) {
        const digitVal = Number(wet % base);
        wet = wet / base;
        yield alphabet.charAt(digitVal);
    }
}

console.log(Array.from(convertBase(100308923948716816384684613592839, "0123456789ABCDEFGH")).reverse().join(""));

答案 1 :(得分:1)

tewathia的评论似乎是这样做的惯用方法,但我想如果你想以艰难的方式去做,你可以编写自己的递归原语,如:

function unreduce(accumulator, operation, stopPredicate, ret) {
    return helper([accumulator, ret])[1]

    function helper(vals) {
        if (stopPredicate(vals[0])) return vals[1];

        return helper(operation(vals[0], vals[1]));
    }
}

您可能希望修改一些位以保留回调的this

我不确定那有多棒。 operation回调需要更新累加器和返回值,这有点尴尬。外部函数无法保存operation不必返回长度为2的数组。

答案 2 :(得分:1)

// These days you can do it in one line:
const unfold = (accumulator, length) => length <= 0 ? accumulator : unfold([length, ...accumulator], length -1)

// invoke it like this:
const results = unfold([], 5)

// expected results:  1,2,3,4,5
console.log(results.join(','))

由于我们正在寻找一种简洁的方法来将给定数量的元素生成为数组,因此此“展开”函数以递归的方式进行操作。

第一个参数是累加器数组。这需要传递,并在保存整个集合时最终返回。第二个参数是限制器。这就是用来确定结果数组尺寸的方法。

在每个调用中,我们首先测试是否达到基本情况。如果是这样,答案很简单:只需返回给定的数组。对于一般情况,我们将再次展开,但使用较小的值,因此我们将一个值添加到累加器中,并减小长度。

由于我们使用了散布运算符和“ compute-if”,因此该函数非常简洁。使用箭头样式还可以避免使用“ function”和“ return”关键字以及大括号。所以整个过程都是单线的。

我基本上将这种技术用作React JSX的for循环替代,其中所有内容都必须是表达式(Array.map())。