0

I have an array of objects:

let reports = [{ inbound_calls: [...], outbound_calls: [...],  outbound_national_calls: [...] },...];

What is the best way to create a new array and assign into a variable:

1st approach - one loop:

let inbound_calls = []; outbound_national_calls = [], outbound_calls = [];

reports.forEach((e) => {
 inbound_calls.push(e.inbound_calls);
 outbound_national_calls.push(e.outbound_national_calls);
 outbound_calls.push(e.outbound_calls);
})

2nd approach:

let inbound_calls = this.reports.map((report) => report.inbound_calls)
let outbound_national_calls = this.reports.map((report) => report.outbound_national_calls)
let outbound_calls = this.reports.map((report) => report.outbound_calls)

I'm starting to learn functional programming, and want to apply it to my code, I would go with first approach (one loop), but as I did research about functional programming I think the second one is the right way (much cleaner) but, I'm not sure, what is less expensive operation?

2
  • 1
    The forEach() loop will be the less expensive operation. If performance is an absolute necessity, the traditional for() loop is the fastest loop in the JS runtime. Commented May 14, 2018 at 16:10
  • 1
    @MátéSafranka yeah. Technically, with this code, the easiest thing would be to do inbound_calls = reports.inboundCalls.slice(). However, I think the question still has merit, probably it would make more sense if reports contains something like [ { inbound_calls: ...} ] Commented May 14, 2018 at 16:14

3 Answers 3

3

If your ultimate goal is to create three variables out of the object, you may use object destructuring as follows. No loops required.

let reports = {
  inbound_calls: [1, 2, 3],
  outbound_calls: [4, 5, 6],
  outbound_national_calls: [7, 8, 9]
};

let {inbound_calls, outbound_calls, outbound_national_calls} = reports;
console.log(inbound_calls);
console.log(outbound_calls);
console.log(outbound_national_calls);

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

6 Comments

And the least expensive operation yet! Nice answer.
Note that this doesn't copy the arrays. Any mutation to the variables will also mutate the original arrays.
@ibrahimmahrir -- What OP has coded, does the same thing. OP didn't mention anywhere that he wants to create a copy. Still, if the copy is needed, using slice is obviously preferred.
@31piy No, it doesn't. OP's code is wrong anyway. Also OP is clearly intending to copy the items. Not sure if that is really what he wants but sure not what his code is aiming for.
Thanks for that but I had mistake in my question reports is array, so I can't use destruction like this there...
|
1

If you want to copy the arrays, just use Array#slice (the 0 passed is optional as it is the default start index so you can omit it if you want) like:

let inbound_calls = reports.inbound_calls.slice(0),
    outbound_national_calls = reports.outbound_national_calls.slice(0), 
    outbound_calls = reports.outbound_calls.slice(0);

or Array.from like:

let inbound_calls = Array.from(reports.inbound_calls),
    outbound_national_calls = Array.from(reports.outbound_national_calls), 
    outbound_calls = Array.from(reports.outbound_calls);

3 Comments

You don't need to supply 0 to .slice() - that's the default value. Calling it without an argument is enough.
@vlaz Right. I've added a note regarding it. I still think providing it is better as it is much clearer.
I can see your point. I did actually use to do that but at some point I stopped. I can definitely see merits for either way of calling this. In the beginning I did it because something else required a start parameter and it was less confusing to me to always supply it to .slice(). Later on, I came back to JS after doing something else and I actually forgot to add the index for a while until I came across some older code. It's not a big deal either way, so as long as you're consistent, it should be fine.
0

What you're essentially doing is a matrix transposition:

const report = (inbound_calls, outbound_calls, outbound_national_calls) =>
    ({ inbound_calls, outbound_calls, outbound_national_calls });

const reports = [report(1,2,3), report(4,5,6), report(7,8,9)];

const transpose = reports =>
    report( reports.map(report => report.inbound_calls)
          , reports.map(report => report.outbound_calls)
          , reports.map(report => report.outbound_national_calls) );

console.log(transpose(reports));

Now, depending upon your application the fastest way to transpose a matrix might be not to transpose it at all. For example, suppose you have a matrix A and its transpose B. Then, it holds that for all indices i and j, A[i][j] = B[j][i]. Consider:

const report = (inbound_calls, outbound_calls, outbound_national_calls) =>
    ({ inbound_calls, outbound_calls, outbound_national_calls });

const reports = [report(1,2,3), report(4,5,6), report(7,8,9)];

// This is equivalent to transpose(reports).outbound_calls[1]
const result = reports[1].outbound_calls;

console.log(result);

That being said, your second approach is IMHO the most readable.

Comments

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.