在Javascript中通过数组映射函数数组

时间:2017-01-24 15:12:21

标签: javascript arrays functional-programming

我经常需要将函数列表(处理器)映射到浮点数据的几个数组(通道),所以我写了一个辅助函数...

const mapMany = function(processors, channels){
  processors.forEach( function(processor){
    channels = channels.map( (channel) => channel.map(processor) );
  });
  return channels;
};

这读取OK(至少对我来说!)但是将函数数组映射到另一个数组看起来像是一个通用的东西我不禁想知道它是不是“一件事”就是有更好的/内置的in / canonical方式实现这个“Map Many”类型的功能,如果是这样,它的正确名称是什么?

4 个答案:

答案 0 :(得分:5)

是的,有更好的方法来实现这一点。不要使用diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index 39ed750..c358b9b 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -329,18 +329,11 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO if (topLevel) { if ((type == Qt::Window || dialog || tool)) { if (!(flags & Qt::FramelessWindowHint)) { - if (!(flags & Qt::MSWindowsFixedSizeDialogHint)) { + style |= WS_POPUP; + if (!(flags & Qt::MSWindowsFixedSizeDialogHint)) style |= WS_THICKFRAME; - if(!(flags & - ( Qt::WindowSystemMenuHint - | Qt::WindowTitleHint - | Qt::WindowMinMaxButtonsHint - | Qt::WindowCloseButtonHint - | Qt::WindowContextHelpButtonHint))) - style |= WS_POPUP; - } else { - style |= WS_POPUP | WS_DLGFRAME; - } + else + style |= WS_DLGFRAME; } if (flags & Qt::WindowTitleHint) style |= WS_CAPTION; @@ -424,6 +417,14 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO if (!q->testAttribute(Qt::WA_Resized)) { w = sw/2; h = 4*sh/10; + if (extra) { + int dx = rect.right - rect.left; + int dy = rect.bottom - rect.top; + w = qMin(w, extra->maxw + dx); + h = qMin(h, extra->maxh + dy); + w = qMax(w, extra->minw + dx); + h = qMax(h, extra->minh + dy); + } } if (!wasMoved) { x = sw/2 - w/2;

forEach

但不,没有内置因素,也没有规范名称。它是一个非常具体的功能,但可以简单地由标准构建块组成。

答案 1 :(得分:4)

我认为您正在寻找compose。它看起来像这样:

const compose = function (...fns) {
    const rest = fns.reverse();
    const first = rest.shift();
    return function (...args) {
        return rest.reduce((acc, f)=>f.call(this, acc), first.apply(this, args));
    };
};

现在你可以编写这样的函数:

const stringDouble = compose(String, x=>x*2);
stringDouble("44"); //==> "88"

["22","33","44"].map(stringDouble);
//=> ["44", "66", "88"]

在你的情况下,你可以像这样编写你的函数:

const mapMany = function(processors, channels){
  // compose iterates from last to first so i apply reverse
  const fun = compose.apply(undefined, processors.reverse());
  return channels.map(fun);
}; 

使用reduce优于您自己的代码和其他答案的优势在于,这不会在流程中生成processors.length数组,而只会生成compose数组。

有些图书馆提供this。它是函数式编程中的常见功能。

其他映射函数(如Underscore中的映射函数)允许您设置this。然后类方法将在我将a = float(sys.argv[1]) b = float(sys.argv[2]) c = float(sys.argv[3]) equation = ("{}x**2+{}x{}".format(str(a).rstrip('0').rstrip('.'),str(b).rstrip('0').rstrip('.'),str(c).rstrip('0').rstrip('.'))) print equation 传递给基础函数时起作用。

答案 2 :(得分:1)

因为Bergi指出它只是简单地减少我正在寻找,将它分成两个函数使它更清晰......

const applySingleProcessor = function(channels, processor){
  return channels.map( channel => channel.map(processor) );
};

const applyMultipleProcessors = function(processors, channels) {
  return processors.reduce(applySingleProcessor, channels);
};

简单易懂!

答案 3 :(得分:0)

虽然我通常会使用.reduce()作为@Bergi,但这里只是一个简单的递归.map()解决方案而没有.reduce();

var channels = [[1,2,3,4],[5,6,7,8], [857,1453,1881,1071]],
  processors = [x => x+1, x => x*x, x => Math.sqrt(x), x => x-1],
     mapMany = (processors, channels) => processors.length ? (channels = channels.map(c => c.map(processors[0])),
                                                              mapMany(processors.slice(1),channels))
                                                           : channels;
console.log(mapMany(processors,channels));