2

I am writing a function that iterates through all of the members of an array that are passed in as a parameter to the function. Each member of the array would be output to the console.

And then I need to expand on that function so that it will work whether an ARRAY or an OBJECT is passed in as the parameter to the function. This means I need to know how to distinguish whether or not the parameter is an ARRAY or an OBJECT.

Currently I am using a for loop and I created a forEach version too for variation.

See my codes:

function iterateMembers(arg){
  for(let i = 0; i < arg.length; i++){
    console.log(arg[i]);
  }   
}

let output = iterateMembers(arr);
console.log(output);


// forEach Version

function iterateMembers(arg){
  arg.forEach((item) => console.log(item));    
}


let arr = ['nci', 12, 'blog', 15];
let obj = {
  firstname: 'nci',
  lastname: 'g',
  age: 21
};

let output = iterateMembers(arr);
console.log(output);

One big problem here is that when I passed in the obj it will not return anything and will return an error on both ES5 and ES6 version. This should work whether an ARRAY or an OBJECT is passed in as the parameter to the function. This means I need to know how to distinguish whether or not the parameter is an ARRAY or an OBJECT.

Based on what it is then will need to handle them appropriately and output the contents of the array or object to the console. I need to create this function for both ES5 and ES6 version. Any idea what am I missing? How can I do that?

  • Whenever the parameter passed is an `object`, then you should be looping the `Object.keys(obj)` (to get the keys, or .values to get the values.. Or just loop the keys and get the values with the keys). In your example, the array has a single dimension (values), while objects have Key->Value pairs, hence you need to grab the Object keys and loop them. The approach is different, this is likely what you are missing. – briosheje Aug 06 '17 at 15:47

4 Answers4

2

you can use for (variable in object) {

function iterateMembers(arg){
    for(var key in arg) 
        console.log(arg[key]);
}


let arr = ['sam', 12, 'norton', 15];
let obj = {
  firstname: 'sam',
  lastname: 'norton',
  age: 21
};
iterateMembers(arr);
iterateMembers(obj);
Dij
  • 9,761
  • 4
  • 18
  • 35
1

You could just iterate over the keys of either an object or an array.

function iterate(object) {
    return Object.keys(object).map(k => object[k]);
}

let array = ['sam', 12, 'norton', 15];
let object = { firstname: 'sam', lastname: 'norton', age: 21 };

console.log(...iterate(array));
console.log(...iterate(object));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

You can check the constructor of the object that was passed into your iterateMembers function and use an if statement to distinguish between the two:

function iterateMembers(arg) {
    if(arg.constructor === Array) {
        for(var i=0;i<arg.length;i++) {
            var element = arg[i];
            console.log(element);
        }
    } else {
        for(var i=0;i<Object.keys(arg).length;i++) {
            var index = Object.keys(arg)[i];
            var element = arg[index];
            console.log(element);
        }
    }
}

var obj = {'key1': 'val1', 'key2': 'val2', 'key3': 'val3'};
var arr = ['key1', 'key2', 'key3'];

iterateMembers(arr);//Outputs key1, key2, key3
iterateMembers(obj);//Outputs val1, val2, val3
afterburn
  • 148
  • 1
  • 10
  • Why not use `Array.isArray` – Icepickle Aug 07 '17 at 12:47
  • That would work as well but I believe accessing a constructor is slightly faster than calling a method as demonstrated [here](https://jsfiddle.net/pwmd82xc/). Furthermore I believe the [constructor](https://developer.mozilla.org/nl/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor) is guaranteed to work in every browser while [Array.isArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray) is less supported according to the MDN web docs. In any case, the differences are negligible. It boils down to personal preference I think. – afterburn Aug 07 '17 at 13:14
  • The example you send could make use of `console.time(label)` and `console.timeEnd(label)` ;) Also saying less supported is somewhat over the top, considering that minimum version of internet explorer is version 9, which is if I am correct at most Windows XP, which is no longer supported. People who are still in XP should experience a less working web, as an incentive to go to a working os... Besides, for me both examples had 0 ms ;) – Icepickle Aug 07 '17 at 13:25
  • Like I said, the differences are negligible ;) – afterburn Aug 07 '17 at 13:29
  • Icepickle's comments sparked my interest in whether or not accessing the constructor is actually faster than calling the Array.isArray method, so I've created a more elaborate test [here](https://jsfiddle.net/6dk6zkrh/). The results seem to vary, so judge for yourself. – afterburn Aug 08 '17 at 10:01
  • `Array.isArray` seems to win on Vivaldi (chrome) ;) At least, most of the time, which seems to indicate that there is no need to use the constructor – Icepickle Aug 08 '17 at 10:53
0

In order to distinguish between array and object you can see this answer: Check if object is array?

In order to iterate OBJECT keys / values you can use:

iterateMembers(Object.keys(obj))
or
iterateMembers(Object.values(obj))
José Quinto Zamora
  • 2,070
  • 12
  • 15