1

Since the title is not easy to get, I'll provide an example :

var myObject = {
  "myArray": [{
"hashKey": "someHashkey1",
"data": "someData1"
  }, {
"hashKey": "someHashkey2",
"data": "someData2"
  }, {
"hashKey": "someHashkey3",
"data": "someData3"
  }]
};
        

I have "myObject" containing "myArray", and now I would like to efficiently find the index of the object having, for instance, the hashKey "someHashKey2".

I could build my own loop to check all elements in the array, but :

  1. is there a built-in way to do it ? Something like indexOf() ?

  2. is there a npm tool for that kind of need (I work in Node.js)

  3. is there an efficient way to work here ? some bad way to avoid ?

[EDIT :] My efficiency question is due to the fact that I will have to do this operation for basically all the hashKeys. I just found this question which has a "lookup" answer that could help. Still in the process of understanding it all...

3
  • What you have has nothing to do with JSON. Commented Jul 20, 2016 at 18:54
  • I am curious to know which way you have attempted... Commented Jul 20, 2016 at 18:57
  • why do you call it hashkey and does not use it for it? Commented Jul 20, 2016 at 19:31

3 Answers 3

1

You can simply use Array.prototype.findIndex to get index of every item you want.

var myObject = {"myArray": [{"hashKey": "someHashkey1", "data": "someData1"}, {"hashKey": "someHashkey2", "data": "someData2"}, {"hashKey": "someHashkey3", "data": "someData3"}] };

console.log(myObject.myArray.findIndex(i => i.hashKey === 'someHashkey2'));

If search call happens most of the time then you can use this hash to check or access your values:

Old Fashioned way

var myObject = {"myArray": [{"hashKey": "someHashkey1", "data": "someData1"}, {"hashKey": "someHashkey2", "data": "someData2"}, {"hashKey": "someHashkey3", "data": "someData3"}] };


hash = Object.create(null);
myObject.myArray.forEach(i => hash[i.hashKey] = i)

console.log('someHashkey2' in hash);
console.log(hash.someHashkey2);

New style

var myObject = {"myArray": [{"hashKey": "someHashkey1", "data": "someData1"}, {"hashKey": "someHashkey2", "data": "someData2"}, {"hashKey": "someHashkey3", "data": "someData3"}] };

var map = new Map;
myObject.myArray.forEach(i => map.set(i.hashKey, i));

console.log(map.has('someHashkey2'));
console.log(map.get('someHashkey2'));

Benefit of using map is that it allows you store anything as key and not just string

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

8 Comments

@FelixKling I don't think that would be necessary. Isn't that description enought?
@mortezaT – A plain code without explanation is never helpful...Care to explain what is happening...
NOTE: findIndex is not supported in Internet Explorer as per the docs.
@TadDonaghe – OP is under context of node so IMO, Browser Support should not be the concern...
Thanks for this solution : I think this is the best answer to the question as I wrote it. However, I'm accepting a solution which makes use of my hash keys. Do you think it's a mistake to convert myArray into an object ?
|
0

If you have an hash key I would recommend you to convert the array to an object and then you could find the object using the hash key like this: myObject.myArray["someHashkey1"]

var myObject = 
    { "myArray" : 
       {
         "someHashkey1":{
          "hashKey": "someHashkey1",
          "data": "someData1"
         },
         "someHashkey2":{
          "hashKey": "someHashkey2",
          "data": "someData2"
         }
       }
     };
     console.log(myObject.myArray["someHashkey1"]);

Here is a small performance test for array vs hash object as you can see there is a small difference between finding the same key in an array in an object. the object is a bit faster.

2 Comments

You're so right. With hash keys I'm better off that way. Only one question before accepting this answer : is there any loss in time efficiency when using your answer instead of an array-built structure ? (I'm not dealing with huge data, but I'm still wondering...)
lovely, you are my hero (for an hour) ;-)
0

Whenever you want to get one (non-boolean) value out of an array, you almost always want reduce:

var index = myObject.myArray.reduce((index, record, i) => {
  if (index !== -1 || !('somekey' in record)) {
    return index;
  } else {
    return i;
  }
}, -1);

Or 'golfed':

var index = myObject.myArray.reduce((i, x, j) => {i || x.somekey ? i : j},-1);

2 Comments

reduce is not a good choice, because you need to iterate until the end, even if ther is a find in the middle or at the beginning. better use some.
@NinaScholz but some only gets you a boolean, not an index. And unless the data set is exceedingly large, or the function is called quite often on different data sets, I fail to see how the microseconds difference between this and a for loop with a break matters in the slightest, whereas this is a pretty clear win in terms of testability and compactness.

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.