0

Let's say I have a function that receives either an object or an array. I would like to iterate through each element, and do something to each element as I go. I know that I can iterate through an array with forEach() or a normal for loop. I can also iterate through an object and array with a for in loop. But unlike the array case I have to check the object's elements with hasOwnProperty().

Can I just apply some general piece of code to both arrays and objects?

Update. This is my attempt for some object/array called value, but no console messages appear for the object case:

keysArray = Object.keys(value);
for(let key in keysArray) {
    console.log(value[key])
}
cham
  • 8,666
  • 9
  • 48
  • 69
  • You could use `Object.entries`. – Sebastian Simon Mar 23 '18 at 02:32
  • Perhaps [lodash collection methods](https://lodash.com/docs/4.17.5#map) are of use to you? – vapurrmaid Mar 23 '18 at 02:34
  • Show some code that you understand we can take it from there. – zer00ne Mar 23 '18 at 02:38
  • "*I have to check the object's elements with hasOwnProperty()*" - no, [you probably don't](https://stackoverflow.com/q/45014347/1048572). And no, you [shouldn't use `for…in` enumerations on arrays](https://stackoverflow.com/q/500504/1048572). – Bergi Mar 23 '18 at 02:38

2 Answers2

1

You could use

function* entries(o) {
    if (Array.isArray(o))
        for (let i=0; i<o.length; i++)
            yield [i, o[i]];
    else
        for (const p in o)
            yield [p, o[i]];
}
// or using builtin iterators:
function entries(o) {
    return Array.isArray(o) ? o.entries() : Object.entries(o).values();
}

and call it as

for (const [key, value] of entries(something)) {
    console.log(key, value);
}

Of course you can do a similar thing to get just the keys or just the values.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thank you @Bergi. I'll have to look this up. Does the `*` declare a generator? – cham Mar 23 '18 at 02:54
  • @chamilton Yes, that's a [generator function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*) – Bergi Mar 23 '18 at 03:05
1
// whatever can be object or array

function doSth(whatever) {
  let myLoopable = whatever;

  // obj to array
  if (!Array.isArray(whatever)) {
    myLoopable = Object
      .keys(whatever) // get array of keys
      .reduce((acc, curKey) => [...acc, whatever[curKey]], []); // get array of values
  }

  myLoopable.forEach(value => console.log(value));
}

This is an example, not the best, you must do your own to check if it is object or not to make sure your function not failed

Khoa
  • 2,632
  • 18
  • 13
  • I think you want `map`, not `reduce`. – Bergi Mar 23 '18 at 03:06
  • `map` is another choice :D. It's up to you – Khoa Mar 23 '18 at 03:07
  • Well it would be a great improvement in simplicity, readability and performance… – Bergi Mar 23 '18 at 03:11
  • for performance, I am sure I have no idea. for simplicity & readability, i am sure it equals. `map` and `reduce` have theirs own meaning and approach. I must agree that most people are not comfortable with `reduce`, but it's not because complexity. – Khoa Mar 23 '18 at 03:16
  • Yes, they have their own meaning - and when you mean to map the array to a new one, you should not use `reduce`. – Bergi Mar 23 '18 at 03:37
  • It would be nice if you could give me some references for why "you should not use reduce". Thanks – Khoa Mar 23 '18 at 03:42
  • I think I already gave you enough reasons. I can't provide more resources, you'll have to believe me. – Bergi Mar 23 '18 at 03:47
  • wow, you just say by yourself, no number, no chart, no information shows why "should NOT use `reduce` when mapping an array to a new one", or how fast to use `map` over `reduce`. Ok, if you don't want to share knowledge, ok, fine. – Khoa Mar 23 '18 at 04:00
  • What chart, what number do you need to judge simplicity and readability? Apply a code metric you believe in. If you want to compare performance, do a benchmark - I don't need to do it for you. – Bergi Mar 23 '18 at 04:49
  • Have you tried writing a solution with `map`, do you know what it would look like? Please post it. The comparison should be obvious then. – Bergi Mar 23 '18 at 04:50
  • Ok, end here, you gave a statement, I asked for an evidence. You didn't want to give it. I also don't have time and duty to prove what you said. You even didn't read my question. I've never mention about simplicity and readability in my question. – Khoa Mar 23 '18 at 07:59