0

We have a simple object with methods

var o = {
   fn : (a)=>{}
}

We than add numerical indexed sub objects to it

o[0] = {};
o[1] = {};

So now we have a mixture of methods and numeric properties

o = {
   "0" : {}...
   "1" : {}...
   fn  : (a)=>{}
}

This is helpful for various reasons... seems totally legit and possible in JS.

We preferred an object with numeric properties, instead of an array with methods.

The Question : is there a way to get indexOf, splice, various Array.prototype methods to work with this?

We have tried stuff like :

[].indexOf.call(o,_index) // didn't work

...

Is the only solution would be to construct our object as an array, appending methods to it? or maybe there is another way to apply Array.prototype methods on an object?

8
  • 3
    This is object not array, and why you need indexOf when you can directly access o[index] and for any array method use object.keys(), Object.values or Object.entries and then access key and values Commented Apr 17, 2019 at 7:58
  • 1
    Maybe you would be happier starting with an array and adding a fn property to it. Commented Apr 17, 2019 at 7:59
  • 1
    "is there a way to get indexOf, splice, various Array.prototype methods to work with this" And how would this work with an object exactly? Commented Apr 17, 2019 at 8:00
  • 1
    You can access object by it's key and you have delete method to remove particular key/value Commented Apr 17, 2019 at 8:04
  • 1
    You can do all these operations on object as well. For ex: indexOf would be Object.keys(o).find(k=> o[k] === value). And splice would be to loop from start to end index and delete o[index] Commented Apr 17, 2019 at 8:07

2 Answers 2

1

If you give you object a length property you can hack your way into the array methods through the back door. I suspect nobody would really advise doing this, but the way the JS spec is written to look for length and iterate over sequential numbers, many of these methods will work:

let o = {
  "0" : "zero",
  "1" : "one",
  length: 3,
  fn  : (a)=>{},
  "2" : "Two",
}

console.log(Array.prototype.slice.call(o, 1))

console.log(Array.prototype.indexOf.call(o, "Two"))

Array.prototype.splice.call(o, 1, 0, "Three")
// spliced in and adjusted length
console.log(o)

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

Comments

1

You could take Object.assign with an array as target. The result is an array with all array methods.

var o = { 0: 'foo', 1: 'bar', fn: a => {} };

console.log(Object.assign([], o).indexOf('bar'));

For IE, you could reduce the keys.

var o = { 0: 'foo', 1: 'bar', fn: a => {}, '1.1': 'wrong', '-1': 'wrong', 1e10: 'wrong' },
    array = Object.keys(o).reduce((r, i) => {
        if (isNaN(i) || +i < 0 || +i !== +i | 0) return r;
        r[i] = o[i];
        return r;
    }, []);

console.log(array.indexOf('bar'));
console.log(array);

Comments

Your Answer

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