javascript – ko.utils.arrayMap,但只返回数组的一部分

我正在使用一些出色的Knockout实用程序函数http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html

我想做一个arrayMap来根据条件选择某些属性,例如

return ko.utils.arrayMap(myObservableArray(),function (item) {
    return item.Label;
});

比方说,这会产生以下输出

[null,"","SomeLabel",null,"SomeOtherLabel"]

我想根据条件选择属性,所以我尝试:

return ko.utils.arrayMap(myObservableArray(),function (item) {
    if (item.Label && item.Label !== "") {
        return item.Label;
    }
});

然而,你最终得到一个数组,如:

[undefined,undefined,"SomeOtherLabel"]

我也试过这个:

return ko.utils.arrayMap(myObservableArray(),function (item) {
    return (item.Label && item.Label !== "") ? item.Label : false;
});

但你得到:

[false,false,"SomeOtherLabel"]

所以我必须这样做:

var itemsWithLabels = ko.utils.arrayFilter(myObservableArray(),function (item) {
    return (item.Label && item.Label !== "");
});
return ko.utils.arrayMap(itemsWithLabels,function (item) {
    return item.Label;
});

哪个会给我:

["SomeLabel","SomeOtherLabel"]

有没有更有效的方法来实现这一点,一次性使用ko.utils或类似?

解决方法

正如您所注意到的那样,对于ko.utils.arrayMap,预计您的回调会返回一些内容.所以这是一个’哑函数’,总是将回调的返回值附加到数组.返回undefined,null或false不会忽略结果数组中的值.

arrayFilter不允许修改过滤的项目:原始项目将被推送到结果数组.

简而言之,使用ko.utils.array *函数无法更有效地完成此操作.您可以将它们组合起来并使代码更加冗长,甚至可能将它们放入计算中:

var itemsWithLabels = ko.computed(function () {
    return ko.utils.arrayMap(ko.utils.arrayFilter(myObservableArray(),function (item) {
        return item.Label && item.Label.length;
    }),function (filteredItem) {
        return filteredItem.Label;
    });
});

但这是你能做的最好的事情.我选择先应用过滤器,然后进行映射,因为在我看来映射会比过滤更昂贵.但这只是一种预感.

也许像Underscore这样的库提供了直接执行此操作的方法.

自己编写这样的方法也相当容易(如果你愿意的话可以把它放在ko.utils中)

ko.utils.arrayMapFilter = function (array,mapping) {
        array = array || [];
        var result = [],mapResult;
        for (var i = 0,j = array.length; i < j; i++) {
            mapResult = mapping(array[i]);
            if (mapResult) {
                result.push(mapResult);
            }
        }
        return result;
    },

你的映射回调现在可以返回虚假值,如0,“”,null或undefined,它们不会在数组中结束.

如果你想要允许上面的一些值(比如0或“”),那么只需更改一行:

if (mapResult)

更严格的事情,如:

if (mapResult !== undefined && mapResult !== null)

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...