Get Key From Value in Key-Value Pair - javascript

I have something like this:
var input = [];
var result = {};
input.push({
key: 1,
value: Value
});
result[input[0].key] = input[0].value;
If I want to get the value from key i call result[key], but what if I want to get the Key from a certain value? Any ideas?

You could create an inverse mapping of values → keys; however, there is no guarantee that the values will be unique (whereas the keys must be), so you could map values → array of keys.
function inverseMap(obj) {
return Object.keys(obj).reduce(function(memo, key) {
var val = obj[key];
if (!memo[val]) { memo[val] = []; }
memo[val].push(key);
return memo;
}, {});
}
var a = {foo:'x', bar:'x', zip:'y'};
var b = inverseMap(a); // => {"x":["foo","bar"],"y":["zip"]}
[Update] If your values are definitely unique then you can simply do this:
function inverseMap(obj) {
return Object.keys(obj).reduce(function(memo, key) {
memo[obj[key]] = key;
return memo;
}, {});
}
inverseMap({a:1, b:2})); // => {"1":"a","2":"b"}
Of course, these solutions assume that the values are objects whose string representation makes sense (non-complex objects), since JavaScript objects can only use strings as keys.

A value might have several keys, so I'd recommend iterating over all the keys and adding those that have value into a list.
Do you plan to recurse for complex values?

You could use underscore.js's find method...
var key = _.find(result, function(val) {
return val === 'value';
}).key;
This will search your result for the value and return you the object, then you can grab the key off of it.
Underscore is one of my favorite tools for handling these kinds of things. There's lots of powerful methods in it.

Related

Combine an object of array JS

I have an Object of Arrays like this and I want to combine them(add values to every key )
It's possible to give to every array key: "state" and value: parseFloat(value) or how i can do it?
You can save yourself some typing, and provide some future-proofing in case you later need to handle a different set of territories, by getting the keys from the object itself, and then iterating over those keys:
let val = {};
val = filteredMiles.reduce(
function (previousValue, currentValue) {
const keys=Object.keys(previousValue);
const result={};
keys.forEach(key=>{
result[key]= parseFloat(previousValue[key]))
+parseFloat(currentvalue[key])
})
return result
};
});
console.log(val);

How to find Key value from an object based on the value passed

Thanks for your time.
I have the following object in JavaScript:
{
"key1":"value1,value2,value3",
"key2":"value4,value5,value6"
}
Now I want to parse for a specific value and if the value exists, I want to return the key associated with it. Suppose that I am passing 'value3', it should return key1; if passing value5, it should return me key2 and so on.
What is the best way to implement it using Javascript, keeping in mind the execution time. I have tried using sting manipulation functions like indexOf, substr; but not most effective I believe.
TIA.
Here is a slightly different approach that will generate a map where the key is actually the value of your original values object.
The generated map will be a sort of fast lookup. Just to make things clear this solution is efficient as long as you need to do a lot of lookups. For a single, unique lookup this solution is the less efficient, since building the hashmap requires much more time than just looking up for a single value.
However, once the map is ready, acquiring values through keys will be incredibly fast so, if you need to later acquire multiple values, this solution will be more suitable for the use case.
This can be accomplished using Object.entries and Object.values. Further explanations are available in the code below.
The code below (despite not required) will also take care of avoiding indexOf with limit cases like searching 'value9' over 'value9999' which, on a regular string, would actually work with indexOf.
const values = {
"key1":"value1,value2,value3",
"key2":"value4,value5,value6",
"key3":"value444,value129839,value125390", // <-- additional test case.
"key4": "value9" // <-- additional test case.
};
const map = Object.entries(values).reduce((acc, [key, value]) => {
// If the value is invalid, return the accumulator.
if (!value) return acc;
// Otherwise, split by comma and update the accumulator, then return it.
return value.split(',').forEach(value => acc[value] = key), acc;
}, {});
// Once the map is ready, you can easily check if a value is somehow linked to a key:
console.log(map["value444"]); // <-- key 3
console.log(map["value9"]); // <-- key 4
console.log(map["Hello!"]); // undefined
To me, the fastest and most concise way of doing that would be the combination of Array.prototype.find() and String.prototype.includes() thrown against source object entries:
const src={"key1":"value1,value2,value3","key2":"value4,value5,value6"};
const getAkey = (obj, val) => (Object.entries(obj).find(entry => entry[1].split(',').includes(val)) || ['no match'])[0];
console.log(getAkey(src, 'value1'));
console.log(getAkey(src, 'value19'));
p.s. while filter(), or reduce(), or forEach() will run through the entire array, find() stops right at the moment it finds the match, so, if performance matters, I'd stick to the latter
Lodash has a function for this called findKey which takes the object and a function to determine truthiness:
obj = { 'key1': 'value1, value2, value3', 'key2': 'value4,value5,value6' }
_.findKey(obj, val => val.includes('value3'))
# 'key1'
_.findKey(obj, val => val.includes('value5'))
# 'key2'
Based on your search, you can use indexOf after looping through your object.
Here's an old school method:
var obj = {
"key1":"value1,value2,value3",
"key2":"value4,value5,value6"
}
function search (str) {
for (var key in obj) {
var values = obj[key].split(',');
if (values.indexOf(str) !== -1) return key
}
return null;
}
console.log(search('value1'))
console.log(search('value6'))
Or you can use Object.keys() with filter() method and get the index 0 of the returned array.
var obj = {
"key1":"value1,value2,value3",
"key2":"value4,value5,value6"
}
function search (str) {
return Object.keys(obj).filter((key) => {
const values = obj[key].split(',');
if (values.indexOf(str) !== -1) {
return key
}
})[0]
}
console.log(search('value1'))
console.log(search('value6'))
You can try iterating over each value in your object and then splitting the value on each comma, then checking if the value is in the returned array like so:
const myObj = {"key1":"value1,value2,value3","key2":"value4,value5,value6"}
function findKeyByValue(obj, value) {
for (var key in myObj) {
const valuesArray = myObj[key].split(',')
if (valuesArray.includes(value)) {
return key
}
}
}
const key = findKeyByValue(myObj, 'value5') // returns 'key2'
console.log(key)
EDIT: Changed loop for efficiency, and extracted code to function
This should do it. Just uses Object.entries and filters to find the entries that contain the value you're looking for. (Can find more than one object that has the desired value too)
var obj = {
"key1": "value1,value2,value3",
"key2": "value4,value5,value6"
};
var find = 'value2';
var key = Object.entries(obj).filter(([k, v]) => v.split(',').includes(find))[0][0];
console.log(key);
Might want to check the return value of Object.entries(obj).filter((o) => o[1].split(',').includes(find)) before trying to access it, in case it doesn't return anything. Like so:
var obj = {
"key1": "value1,value2,value3",
"key2": "value4,value5,value6"
};
function findKey(objectToSearch, valueToFind) {
var res = Object.entries(objectToSearch).filter(([key, value]) => value.split(',').includes(valueToFind));
if(res.length > 0 && res[0].length > 0) {
return res[0][0];
}
return false;
}
console.log(findKey(obj, 'value5'));
includes can be used to check whether a value is present in an array. Object.keys can be used for iteration and checking for the match.
function findKey(json, searchQuery) {
for (var key of Object.keys(json)) if (json[key].split(',').includes(searchQuery)) return key;
}
const json = {
"key1": "value1,value2,value3",
"key2": "value4,value5,value6"
}
console.log(findKey(json, 'value5'))
Use Object.entries with Array.prototype.filter to get what the desired key.
const data = {
"key1": "value1,value2,value3",
"key2": "value4,value5,value6"
};
const searchStr = 'value3';
const foundProp = Object.entries(data).filter(x => x[1].indexOf(searchStr) !== -1);
let foundKey = '';
if (foundProp && foundProp.length) {
foundKey = foundProp[0][0];
}
console.log(foundKey);

How to group all values that have the same key into an array

First, sorry if you find the question confusing.
Basically, I have an object like this:
[{"6":6.5},{"4":4.2},{"6":6.3}]
What I want to do, is to remove the duplicated keys but keep there values and push them all into one unique key only, as an array. like this:
[{"6":[6.5, 6.3]}, {"4": 4.2}]
Can anyone suggest a solution?
.reduce() is what you want:
var data = [{"6":6.5},{"4":4.2},{"6":6.3}];
var res = data.reduce((rv, obj) => {
var key = Object.keys(obj)[0];
rv[key] = rv[key] || [];
rv[key].push(obj[key]);
return rv;
}, {});
console.log(res);
Note: This returns data always in the format of arrays (Even if there is one value). If you're looking for the exact format you specified, you just need to add more logic as I've demonstrated below (Although, I wouldn't recommend this approach, as it adds more complication down the line.)
var data = [{"6":6.5},{"4":4.2},{"6":6.3}];
var res = data.reduce((rv, obj) => {
var key = Object.keys(obj)[0];
if (Array.isArray(rv[key])) { // Already is an array
rv[key].push(obj[key]);
} else if (rv[key] !== undefined) { // Has a value. Convert to array
rv[key] = [rv[key], obj[key]];
} else { // Haven't seen this key yet. Set the value
rv[key] = obj[key];
}
return rv;
}, {});
console.log(res);

JavaScript - Filter <key,value> Object by key

I am looking for a short and efficient way to filter objects by key, I have this kind of data-structure:
{"Key1":[obj1,obj2,obj3], "Key2":[obj4,obj5,obj6]}
Now I want to filter by keys, for example by "Key1":
{"Key1":[obj1,obj2,obj3]}
var object = {"Key1":[1,2,3], "Key2":[4,5,6]};
var key1 = object["Key1"];
console.log(key1);
you can use the .filter js function for filter values inside an object
var keys = {"Key1":[obj1,obj2,obj3], "Key2":[obj4,obj5,obj6]};
var objectToFind;
var keyToSearch = keys.filter(function(objects) {
return objects === objectToFind
});
The keyToSearch is an array with all the objects filter by the objectToFind variable.
Remember, in the line return objects === objectToFind is where you have to should your statement. I hope it can help you.
You can create a new object based on some custom filter criteria by using a combination of Object.keys and the array .reduce method. Note this only works in es6:
var myObject = {"Key1":["a","b","c"], "Key2":["e","f","g"]}
function filterObjectByKey(obj, filterFunc) {
return Object.keys(obj).reduce((newObj, key) => {
if (filterFunc(key)) {
newObj[key] = obj[key];
}
return newObj;
}, {});
}
const filteredObj = filterObjectByKey(myObject, x => x === "Key1")
console.log(filteredObj)
Not sure what exactly are you trying to achieve, but if you want to have a set of keys that you would like to get the data for, you have quite a few options, one is:
var keys = ['alpha', 'bravo'];
var objectToFilterOn = {
alpha: 'a',
bravo: 'b',
charlie: 'c'
};
keys.forEach(function(key) {
console.log(objectToFilterOn[key]);
});

How to add Key on existing array javascript

im currently working on a project that uses javascript as it's front end and im having a bit trouble on adding a key on my existing array.
i have an object that i wanted to be converted on array javascript.
here is my code on how to convert my object to array.
var obj = data[0];
var site_value = Object.keys(obj).map(function (key) { return obj[key]; });
var site_key = $.map( obj, function( value, key ) {
return key;
});
the site_value has the value of my objects.
the site_key has the key.
i want to add my site_key to the site_value array as a Key.
example data:
site_value:
0:Array[4]
0:Array[4]
1:Array[1]
2:Array[1]
3:Array[0]
site_key:
Array[49]
0:"AGB"
1:"BAK"
2:"BAN"
3:"BAR"
i want my array to be
AGB:Array[4]
0:Array[4]
1:Array[1]
2:Array[1]
3:Array[0]
Update:
Here is my object.
Array[1]0:
Object
AGB: Array[4]
BAK: Array[4]
BAN: Array[4]
etc.
You have almost done it and I have modified it a bit below to return it as array object,
var obj = data[0];
var site_value = Object.keys(obj).map(function (key) {
var output = {};
output[key] = obj[key];
return output;
});
I might be misunderstanding the question, sorry if I am. I think you would like to use a key "AGB" instead of an integer for an array index. In this case, you would probably be better served to use an object instead of an array. Maybe something like this
var myObject = {
AGB: Array[4],
AGBarrays: [Array[4],Array[1],Array[1],Array[0]]
};
Then you could access AGB by key and your additional arrays by index

Categories