有没有办法在使用函数式编程时获取数组的索引?

时间:2017-06-09 23:44:45

标签: javascript arrays

在javascript中,我想使用函数式编程方法(如filter和map)来转换数组,并希望在结果中包含数组索引。

例如,我有一个数组myArray,我过滤它,并格式化数组中的每个项目,然后将结果连接成一个大字符串。 除非它不包含数组索引,否则这是有效的。

 myArray.filter(myFilterFunction).map(prettyPrinterFunction).join(sep);

以下代码说明了这一点。您可以将其复制/粘贴到节点中进行实验。

class Item {
    constructor(itemNumber){
        this.itemNumber = itemNumber;
    }
    toString(){
        return "Item #" + this.itemNumber;
    }
}

function myFilter(anItem){
    return anItem.itemNumber > 3;
}

function myFormatter(anItem){
    return anItem.toString();
}

// This function does what I want
function formatArray(theArray, theFilter, theFormatter, sep = "\n"){
    var output = "";
    var newLine = "";
    for(ii = 0; ii < listOfObjects.length; ii++){
        if (myFilter(listOfObjects[ii])){
            output += newLine + ii + " " + theFormatter(listOfObjects[ii]);
        }
        newLine = sep;
    }
    return output;
}

var listOfObjects = [];
listOfObjects.push(new Item(5));
listOfObjects.push(new Item(4));
listOfObjects.push(new Item(1));
listOfObjects.push(new Item(8));

var output = formatArray(listOfObjects, myFilter, myFormatter);

console.log(output);

这将输出数组的索引,后跟格式化的结果,这是所需的输出

0 Item #5
1 Item #4
3 Item #8

以下功能样式:

var output = listOfObjects.filter(myFilter).map(myFormatter).join("\n");
console.log(output);

Item #5
Item #4
Item #8

几乎正是我想要的,但它没有与该项目相关联的数组索引。

为了在输出/结果中获取数组索引需要进行哪些更改?

2 个答案:

答案 0 :(得分:1)

签出Array.prototype.map()的语法:

var new_array = arr.map(function callback(currentValue, index, array) {
    // Return element for new_array
}[, thisArg])

可运行示例

https://jsbin.com/bopodehaku/1/edit?js,console

Mozilla参考:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map?v=example

答案 1 :(得分:1)

好的,这很有趣。这是可跑的code

它获得了您正在寻找的输出:

0 Item #5
1 Item #4
3 Item #8

正如其他答案所指出的那样,还有其他参数可以过滤和映射,让您获得一半的参与。要完全到达那里,您需要先创建第一个地图来创建一个保存项目原始序列的临时结构。然后过滤。然后再次映射以在加入之前创建所需的输出数组。凉爽。

以下是主要变化:

myFormatter获取第二个参数,该参数是数组

中元素的索引

并输出一个对象:

{
   index: 0,
   item: theItem
}

因此,在第一个地图之后,我们有一个对象数组,其中包含原始数组中项目的原始索引和项目。然后我们可以过滤掉只有通过过滤器的项目数组。然后,最终地图通过将临时结构中的原始索引与该结构中项目的输出相结合来创建所需的输出。

class Item {
    constructor(itemNumber){
        this.itemNumber = itemNumber;
    }
    toString(){
        return "Item #" + this.itemNumber;
    }
}

function myFilter(element){
    return element.item.itemNumber > 3;
}

function myFormatter(item, index){
    return {index, item};
}

var listOfObjects = [];
listOfObjects.push(new Item(5));
listOfObjects.push(new Item(4));
listOfObjects.push(new Item(1));
listOfObjects.push(new Item(8));

// var output = formatArray(listOfObjects, myFilter, myFormatter);
const output = listOfObjects
  .map(myFormatter)
  .filter(myFilter)
  .map(e => `${e.index} ${e.item}`)
  .join("\n");

console.log(output);