0

I have an object which contains alot of keys and values. I can get any value using the index. But I dont have the full index, I have a part of it, would I be able to get the value based on a part of the index.

Example:

c = {'select':'MyValue',...}

I can get the value using indexing as shown below:

c['select'] = 'MyValue'

I tried to create this function which searches exact value:

function search(nameKey, c){
    for (var i=0; i < c.length; i++) {
        if (c[i].select === nameKey) {
            return c[i];
        }
    }
}

c['select'] will return 'MyValue' but I need to do something like c['Sel'] or c['select'] or c['Select']or c['selected']to return the same 'MyValue'

SMH
  • 1,276
  • 3
  • 20
  • 40

3 Answers3

2

Well the logic doesn't seem to be very clear and it's not quite relevant how it would be matching the key.

But This is a function that may help in the specific cases you showed:

function search(nameKey, obj) {
  if (obj.hasOwnProperty(nameKey)) {
    return obj[nameKey];
  } else {
    var res = Object.keys(obj).filter(function(k) {
      return (k.toLowerCase().indexOf(nameKey.toLowerCase()) > -1) || (nameKey.toLowerCase().indexOf(k.toLowerCase()) > -1);
    });
    return res ? obj[res] : false;
  }
}

Explanation:

  • First we use Object#hasOwnProperty() to check if the object has the searched name as key/property, we return it's value, this will avoid looping all the keys.
  • Otherwise we use Object.keys() to get the keys of the object.
  • Then we use Array#filter() method over the keys array to check if a relevant key exists we return it's value, otherwise we return false.

Demo:

function search(nameKey, obj) {
  if (obj.hasOwnProperty(nameKey)) {
    return obj[nameKey];
  } else {
    var res = Object.keys(obj).filter(function(k) {
      return (k.toLowerCase().indexOf(nameKey.toLowerCase()) > -1) || (nameKey.toLowerCase().indexOf(k.toLowerCase()) > -1);
    });
    return res ? obj[res] : false;
  }
}
var c = {
  'select': 'MyValue'
};
console.log(search("Sel", c));
cнŝdk
  • 31,391
  • 7
  • 56
  • 78
2

Here's an one liner (!):

Assuming your array is in data and the partial index value is in selector:

const result = Object.keys(data).filter(k => k.toLowerCase().indexOf(selector.toLowerCase()) != -1).map(k => data[k]);

The above code returns an Array (coz, there may be more than one match). If you just need a first element, just do result[0].

Veera
  • 32,532
  • 36
  • 98
  • 137
1

You can use Object.keys() to get an array of the property names.

Then find first match using Array#find() to get the key needed (if it exists)

const data = {
  aaaa: 1,
  bbbbbbb: 2,
  cccc: 3
}


function search(nameKey, obj) {
  nameKey = nameKey.toLowerCase();// normalize both to lowercase to make it case insensitive
  const keys = Object.keys(obj);
  const wantedKey = keys.find(key => key.toLowerCase().includes(nameKey));
  return wantedKey ? obj[wantedKey] : false;
}

console.log('Term "a" value:', search('a',data))
console.log('Term "bb" value:', search('bb',data))
console.log('Term "X" value:', search('X',data))

Since search criteria is vague I simply found any match anywhere in the property name and didn't look past the first one found

charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • OP has also asked (in the comments) for a match to be true if the attribute name appears in any part of the search string. If you add that, I think you've got a solution here. – Jonathan M Nov 21 '17 at 21:47
  • Thank you, but It says expecting newline or semicolon on this line: const wantedKey = keys.find(key => key.toLowerCase().includes(nameKey)); – SMH Nov 21 '17 at 21:54
  • @JonathanM `includes()` is not index specific. The match is being made anywhere in the key – charlietfl Nov 21 '17 at 21:54
  • @SMH it might be that your environment is not set up to use arrow functions. Can chnge to `keys.find(function(key)( return key.toLowerCase().includes(nameKey)});` – charlietfl Nov 21 '17 at 21:56
  • Create a working demo that reproduces problem in jsfiddle.net or other sandbox site – charlietfl Nov 21 '17 at 23:08