T
T
toha_man2018-08-16 14:12:21
JavaScript
toha_man, 2018-08-16 14:12:21

Which JS array iteration method to use and how?

There is an array from 0 ... 100 randomly filled with zeros and ones.
Task: using array iteration methods from JS (reduce, map, filter) and not using the second array, get
an array that would contain the indices of elements with ones.
Example.
Let the original array arr = [0, 1, 1, 0, 0, 0, 1]
Then result = [ 1, 2, 6] are the unit indices.
The filter method returns the value of the elements for which callback is true,
the map method always returns something on each call (undefined for an element with 0)
If a second array is needed through forEach, this works, but it is interesting to solve without it. Thanks

Answer the question

In order to leave comments, you need to log in

6 answer(s)
0
0xD34F, 2018-08-16
@toha_man

map/filter:

arr.map((n, i) => n ? i : null).filter(n => n !== null)
// или
arr.map((n, i) => n ? i : NaN).filter(n => n === n)
// или
arr.map((n, i) => !!n && i).filter(Number.isInteger)
// или
arr.map((n, i) => !n || i).filter(n => n !== !0)

reduce:
arr.reduce((acc, n, i) => n ? [ ...acc, i ] : acc, [])
// или
arr.reduce((acc, n, i) => (n && acc.push(i), acc), [])

or, if you need to change the current array, and not create a new one
for (let i = arr.length; i--; ) {
  if (arr[i]) {
    arr[i] = i;
  } else {
    arr.splice(i, 1);
  }
}
// или
arr.reduceRight((_, n, i, a) => n ? a[i] = i : a.splice(i, 1), 0)

I
Ignat Khaylov, 2018-08-16
@ignat_one

For example, like this: (didn't have time a little, the solution is the same as 0xD34F )

let result = arr.map( (item, index) => { return item === 1 ? index : 0 }).filter( item => { return item !== 0});

R
RidgeA, 2018-08-16
@RidgeA

I'll tell you a secret - in the chain with map and filter, 2 additional arrays and 2 passes through the array will be used.
You can use reduce and add the necessary elements to the accumulating array (there will be 1 new array) in 1 pass.

A
Alexey Ukolov, 2018-08-16
@alexey-m-ukolov

The most normal solution is through reduce, that's what it exists for. But there technically is a second array.

arr.reduce((arr, n, i) => {
  if (n === 1) {
    arr.push(i);
  }

  return arr;
}, []);

If you use the map + filter chain, there, too, technically, an intermediate array is used.
What is the purpose of your task? Or is it a theoretical exercise?

T
toha_man, 2018-08-16
@toha_man

Thank you all very much for your replies. I really liked the answers. Absorbed a bit of experience and knowledge)
I did not quite accurately formulate the question. My solution was originally to use 2 arrays like this -

var primes = [], arr = []  ;

primes.forEach( (el, i) => el > 0 ? arr.push(i) : 0 )

And I was wondering how to exclude the use of arr, so all your answers worked for me.
But in terms of speed, it turns out that the reduce option works extremely long. Why do you think? Because of the frequent layout of the [...acc] array ? This is all in the case of a large initial array > 10,000,000 elements .
Here is the result I get in time:
reduce - prntscr. com/kjbdzz
.map().filter - prntscr. com/kjbkc6.forEach
- prntscr . com/kjbksw

A
Anton fon Faust, 2018-08-16
@bubandos

The second array will always be, whatever one may say, if only because you want to get an array at the output.
If you want without the second array - add the result, for example, into a string through a separator.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question