2

I need to create a candle value of an object with sorted keys:

 var obj = [{1: 'a'}, {2:'b'}, {3:'c'}, {4:'d'}, {5:'e'},{6: 'a'}, {7:'b'},{8:'c'}, {9:'d'}, {10:'e'}]

What is the most efficient way to filter this object based on the key?

For instance, I want: the obj filtered with 2 < keys <5 or 6 < keys < 9

(in reality, the keys are timestamp and the values are price data)

EDIT: Here is the object. That is what I meant by sorted

 var obj = [{1: 'a'}, {2:'b'}, {3:'c'}, {4:'d'}, {5:'e'},{6: 'a'}, {7:'b'},{8:'c'}, {9:'d'}, {10:'e'}]
TSR
  • 9,145
  • 14
  • 51
  • 114
  • 1
    Consider using an array of timestamp-price tuples instead, you will have a proper order and can just use `filter`. – Bergi Sep 10 '18 at 13:56
  • Loop over the keys and create a new object. Does not see too difficult. – epascarello Sep 10 '18 at 13:58
  • 1
    Now you have an array of objects with unique keys in each object. That is a horrible structure to work with. do you control the source? – charlietfl Sep 10 '18 at 14:03
  • @charlietfl I can control the strucutre – TSR Sep 10 '18 at 14:04
  • 3
    You've just edited the question to change the format from an object to an array of objects. As long as you can change the data format you should go all the way and take @Bergi's advice to make an array of tuples like `[(1, 'a'), (2, 'b')]` or real objects: `[{time: 1, value: 'a'}]`. It's odd to have data in the keys like this. – Mark Sep 10 '18 at 14:05
  • @TSR `[1, 'a']` is a tuple, `{1: 'a'}` is not – Bergi Sep 10 '18 at 14:06

6 Answers6

4

You can use Object.keys to get the keys and reduce to create a new object with kv pair that met the condition

var obj = {1: 'a', 2:'b', 3:'c', 4:'d', 5:'e',6: 'a', 7:'b',8:'c', 9:'d', 10:'e'}
var res = Object.keys(obj).reduce((acc, elem) => {
 if (elem > 2 && elem < 5) acc[elem] = obj[elem]
 return acc
}, {})
console.log(res)

looks like the obj has been changed
you can filter the new obj a simple .filter()

var res = obj.filter(elem => Object.keys(elem)[0] > 2 && Object.keys(elem)[0] < 5)

if you decided to use the structure in comment

var obj = [{time: 1, value: 'a'},{time: 2, value: 'b'},{time: 3, value: 'c'},{time: 4, value: 'd'}]
var res = obj.filter(elem => elem.time > 2 && elem.time < 5)
Chris Li
  • 2,451
  • 1
  • 6
  • 23
  • which one is more efficient, the first answer or the last one? I will edit my obj accordingly – TSR Sep 10 '18 at 14:17
  • @TSR like Mark Meyer commented, the most sensible approach is to have an array of objects like `[{time: 1, value: 'a'}]` that you can filter, removing the need for Object.keys - it's hard to tell which will be most performant (and in which browser) so i recommend you test it yourself – xec Sep 10 '18 at 14:20
  • i agree, its much better structured that way, for the 2 methods above, i dont there theres a significant difference in runtime – Chris Li Sep 10 '18 at 14:23
  • Is it better like this `[{time: 1, value: 'a'}]` because it is sorted or just because it is strucutred that way, no matter the order? – TSR Sep 10 '18 at 14:27
  • i would say its just better to work with, you dont need to call Object.keys over and over, and less likely for problems – Chris Li Sep 10 '18 at 14:29
0

Simple Objet.keys and reduce to create the new Object with the limited set of keys.

var obj = {1: 'a', 2:'b', 3:'c', 4:'d', 5:'e',6: 'a', 7:'b',8:'c', 9:'d', 10:'e'}

var filtered = Object.keys(obj).reduce((o, k) => {
  const num = Number(k)
  if (num > 4 && num < 9) {
   o[k] = obj[k]
  }
  return o
}, {})

console.log(filtered)

And just a warning that the object keys may not be in order of the numbers. So when you are outputting them, it is not guaranteed that 5 will be before 6.

epascarello
  • 185,306
  • 18
  • 175
  • 214
0

If you are using lodash it is as simple as follows:

const _ = require('lodash');
var obj = {1: 'a', 2:'b', 3:'c', 4:'d', 5:'e',6: 'a', 7:'b',8:'c', 9:'d', 10:'e'};
filtered = _.pickBy(obj,(val,key) =>{return ((key > 2) && (key < 5))})
0

what you need is to sort first the keys and then create new object with the filter and sorted values

i changed it to Map as object keys are not guaranteed to be sorted

const obj =  {1: 'a', 2:'b', 4:'c', 3:'d', 5:'e',6: 'a', 7:'b',8:'c', 9:'d', 10:'e'};

const newObj = new Map();
Object.keys(obj).filter(key =>{

    return (key > 2 && key < 5)
    }).sort().forEach(key=>{
      newObj.set(key,obj[key])


    })
Amit Wagner
  • 2,370
  • 3
  • 9
  • 28
  • 1
    The order of the keys on an object is not guaranteed (even if you sort them before you create a new object) – xec Sep 10 '18 at 14:16
0

As I see, you have an array not an object. Using filter and Object.keys and a condition like ((2<key && key<5) || (6<key && key< 9))

var arr = [{1: 'a'}, {2:'b'}, {3:'c'}, {4:'d'}, {5:'e'},{6: 'a'}, {7:'b'},{8:'c'}, {9:'d'}, {10:'e'}]

var newArr = arr.filter((o=>{
    let k = Object.keys(o);
    if((2<k[0] && k[0]<5) || (6<k[0] && k[0]< 9)){
        return true;
    }
}))

console.log(newArr)
Emeeus
  • 4,104
  • 2
  • 14
  • 32
-1

like this?

keys() will give you an array of object keys, that you can filter

var obj = {1: 'a', 2:'b', 3:'c', 4:'d', 5:'e',6: 'a', 7:'b',8:'c', 9:'d', 10:'e'};
keys(obj).filter((a)=> parseInt(a) > 2 && parseInt(a) <5 );
Eriks Klotins
  • 3,546
  • 1
  • 8
  • 23
  • 3
    Think you mean `Object.keys()`. There is no global `keys()` method – charlietfl Sep 10 '18 at 13:57
  • A key is a string however, so you can't (shouldn't) directly compare it to an integer – Bergi Sep 10 '18 at 13:57
  • 1
    This will just return the keys in an array, not a "filtered object" – xec Sep 10 '18 at 13:58
  • @charlietfl - I didn't think there was a `keys` method either, but in Chrome one does exist. Guessing it's new. – tymeJV Sep 10 '18 at 14:13
  • @tymeJV huh...nothing similar in Firefox. Says it's a "Command Line API". Wonder if that has something to do with dev tools? – charlietfl Sep 10 '18 at 14:16
  • I have never heard of this `keys` function before and also assumed he meant `Object.keys`, but it does seem to run fine in console in Chrome,Firefox and Edge, but only in Chrome does it exist on `window`. Very strange. – xec Sep 10 '18 at 14:31