2

Using functional methods such as map,filter,reduce, how can a nested for loop that is imperative be converted to a declarative function. Using the below as an example:

getTxns: function () {
    var txnsToCheck = [];
    var pages = this.data;
    for (var i = 0; i < pages.length; i++) {
        var page = pages[i];
        var txns = [];
        for (var j = 0; j < page.txns.length; j++) {
            if (page.txns[j].grade) {
                txnsToCheck.push({ page: i, txn: j, virtual: false });
        }
        else {
            txnsToCheck.push({ page: i, txn: 0, virtual: true });
        }
    }

    return txnsToCheck;
},

Below is non working attempt at a functional rewrite, the last map does not work, but I believe illustrates the intent, which is a conditional assignment.

getTxns: function () {
    return this.data.
        map(function (page) {
            return page.txns.
                map(function(txn){
                    if (txn.grade){
                        return {page: txn.page_idx, txn: page.txns.indexOf(txn), virtual: false}
                    } else {
                        return {page: txn.page_idx, txn: 0, virtual: true}
        }
    })
})

I have considered filter, but its not clear if you can traverse back up the chain for a second filter and map in one operation?

Wondering what a working declarative version of the for loop looks like.

Here is an example of what the data schema looks like:

"derived": [
  {
    "page_idx": 0,
    "page_image_url": "",
    "doc_pk": 123456,
    "txns": [
      {
        "page_idx": 0,
        "grade": 0,
        "explanation": "test 1",
        "id": 1962754,
      },
      {
        "page_idx": 0,
        "is_recurring": false,
        "bank_account_pk": null,
        "grade": 0,
        "explanation": "test 2",
        "id": 1962753,
      },
   ]
  },
  {
    "page_idx": 1,
    "page_image_url": "",
    "doc_pk": 2654321,
    "txns": []
  },
  {
    "page_idx": 2,
    "page_image_url": "",
    "doc_pk": 123457,
    "txns": []
  }
]
1
  • Looks like you want a flatMap. You can implement it with reduce. Commented Jul 25, 2015 at 0:47

1 Answer 1

2

What @eclanrs has mentioned can look like this

getTxns: function () {
    return this.data.reduce(function (accumulator, page) {
        return accumulator.concat(page.txns.map(function(txn){ 
                return {
                    page: txn.page_idx,
                    txn: txn.grade ? page.txns.indexOf(txn) : 0,
                    virtual: !txn.grade
                }
        })) ;
    }, []);
},

fiddle

Sign up to request clarification or add additional context in comments.

19 Comments

In the fiddle some of the objects have txn: > 0 and show virtual: true, did you intend to write virtual: !txn.grade ?
Yes sure, I just confused the logic because I have no idea about the business logic you apply and it is not important in terms of the question. I filled page objects randomly just with the fields I saw in your snippet. I provided just the skeleton for transformation not the true algorythm you can copy and paste in your app
This doesn't work in this particular case because virtual is set to true when page is empty, in other words we put virtual in pages where there is no txn at all.
@BarryG could extend your question with a subset of real data so that we could discuss on exact example? So far I've located and fixed only one inconsistency about calculating the resulting index txn. In OP it's 0 for virtual nodes
I have added the data schema.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.