-4

I am storing screen resolutions in an array and I want to lookup for the correct resolution range that is relevant to the user's viewport (i have the width x height of the current window) Given this JS array which holds JSON objects:

[
  {width:100,height:200,data:'myData1'},
  {width:101,height:300,data:'myData2'}, //<-- This one!
  {width:301,height:400,data:'myData3'},
]

How can I lookup for the entry which answers the RANGE of width=160 and height=240 [this range exists in the 2nd entry]

Please ignore the correct array/JSON structure, its just a pseudo code to emphasis what I need to perform.

Broshi
  • 3,334
  • 5
  • 37
  • 52
  • 2
    Ignoring the fact that the element you want doesn't match the search criteria, this is a duplicate of [Get JavaScript object from array of objects by value or property](http://stackoverflow.com/questions/13964155/get-javascript-object-from-array-of-objects-by-value-or-property) – JJJ Feb 29 '16 at 16:46
  • 1
    the middle entry does not have a width of 150 and height of 250. – Alex Harris Feb 29 '16 at 16:47
  • your object has a ',' more – CMedina Feb 29 '16 at 16:48
  • Sorry, edited it to better explain what I need – Broshi Feb 29 '16 at 16:49
  • 1
    ignore the fact that it's json. you don't deal with json directly. You decode the json into a native structure, and then it's a native structure that you access like you would any OTHER native structure. – Marc B Feb 29 '16 at 16:51
  • @Juhana I wasnt clear about my purpose, re-edited the question, hope its clear now. – Broshi Feb 29 '16 at 16:59
  • 1
    you keep using the word range but `width = 160` is not a range on width. Do you mean width is less than 160 and height is more than 240? – Quince Feb 29 '16 at 17:13
  • Never mind, I am adding 'min_width' and 'max_width' to each entry and that will solve my problem. – Broshi Mar 01 '16 at 06:56
  • @Broshi: DO not change your model (data) to fit your functional needs. Just change your function to expect a range. See [my response](http://stackoverflow.com/a/35705030/1762224) below. – Mr. Polywhirl Mar 01 '16 at 11:50

2 Answers2

3

Use Array.prototype.filter:

var arr = [
  {width:100,height:200,data:'myData1'},
  {width:150,height:250,data:'myData2'},
  {width:301,height:400,data:'myData3'}
]

var item = arr.filter(function(item){ return item.width === 150 && item.height === 250 })[0];

JSFIDDLE.

BTW, The filter method will return an array of matches. I selected the first match.

Amir Popovich
  • 29,350
  • 9
  • 53
  • 99
-1

You can create your own filter function. This only works for sparse properties. If you enter a scalar value and it matches the expected type it will compare the values for equality, but if your expected value is a range then the actual value will be tested for the provided domain.

var data = [
  { width: 100, height: 200, data: 'myData1' },
  { width: 101, height: 300, data: 'myData2' }, //<-- This one!
  { width: 301, height: 400, data: 'myData3' }
  // ...
];

function findWhere(list, props) {
  return list.filter(function(item) {
    return Object.keys(item).reduce(function(total, key) {
      if (item.hasOwnProperty(key)) {
        var expected = props[key];
        var actual = item[key];
        if (typeof expected === typeof actual) {
          return total + (expected === actual ? 1 : 0);
        } else {
          if (expected instanceof Array) {
            return total + (actual >= expected[0] && actual < expected[1]);
          } else {
            return total;
          }
        }
      }
      return total;
    }, 0) === Object.keys(props).length;
  });
}  

var result = findWhere(data, { width: [100, 200], height: [300, 400] });

document.body.innerHTML = '<pre>' + JSON.stringify(result, null, 2) + '</pre>';
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132