Lowercase JavaScript object values - javascript

I have an array of JavaScript objects:
var obj = [{key1: Value1, key2: VALUE2},{key1: Value1, key2: VALUE2}];
I want the value of the key2 to be in lowercase, like this:
var obj = [{key1: Value1, key2: value2},{key1: Value1, key2: value2}];
How can I change the value from lowercase to uppercase?

If I understand your question correctly, you want to change the value of each object's key2 property, to be a lowercase string (I'm assuming they're strings).
You can do this with a simple map.
obj = obj.map(function(a) {
a.key2 = a.key2.toLowerCase();
return a;
});
There are some differences in all the answers given here, surrounding object references. In my answer above, the array itself will be a new reference, but the objects inside will remain as the same reference. To clarify this by way of example
var mapped = obj.map(function(a) {
a.key2 = a.key2.toLowerCase();
return a;
});
console.log(obj === mapped) // false
console.log(obj[0] === mapped[0]) // true
If you're using a for loop or a forEach array function, then the array reference will remain the same.
See this fiddle for reference.

You can use built-in array functions like forEach or map
// in-place
obj.forEach(function (item) {
item.key2 = item.key2.toLowerCase()
})
or
var mapped = obj.map(function (item) {
return Object.assign(item, { key2: item.key2.toLowerCase() });
})

You just have to loop through the array and lowercase the value of key2 for every object.
var objects = [{key1: "Value1", key2: "VALUE2"},{key1: "Value1", key2: "VALUE2"}];
for(var i = 0;i < objects.length;++i) {
objects[i].key2 = objects[i].key2.toLowerCase();
}

You could iterate the array and the keys, you want to change, and assign the lowercase value if you have a string.
var array = [{ key1: 'Value1', key2: 'value2' }, { key1: 'Value1', key2: 'value2' }];
array.forEach(function (a) {
['key2'].forEach(function (k) {
if (typeof a[k] === 'string') {
a[k] = a[k].toLowerCase();
}
});
});
console.log(array);
A version with a fixed key.
var array = [{ key1: 'Value1', key2: 'value2' }, { key1: 'Value1', key2: 'value2' }];
array.forEach(function (a) {
if (typeof a.key2 === 'string') {
a.key2 = a.key2.toLowerCase();
}
});
console.log(array);

Concept:
Create a function to lowercase an item based on the given key.
Then, iterate items and parse each item on those function.
Create a function to lowercase the item based on the given key:
function lowerObj(obj, key) { obj['' + key] = obj['' + key].toLowerCase(); return obj; }
Iterate items and parse each item on those function
var newObj = obj.map((item) => {return lowerObj(obj, 'your_key')});
So, you will get newObj with lower case for the item with the given key.
Example
function lowerObj(obj, key) {
obj['' + key] = obj['' + key].toLowerCase();
return obj;
}
var obj = [{key1: 'Value01', key2: 'Value02'}, {key1: 'Value11', key2: 'Value12'}];
var newObj = obj.map((item) => {return lowerObj(item, 'key2')});
console.log(JSON.stringify(newObj, null, 3));

caseInsensitivity = function(obj) {
Object.keys(obj).forEach(k => {
if(typeof obj[k] == 'string') {
obj[k] = obj[k].toLowerCase();
}
else if(typeof obj[k] == 'object') {
caseInsensitivity(obj[k]);
}
else {
}
});
return obj;
}
To convert all values even if the values are nested objects or arrays.

Assuming you had a JSON object like.
"params": {
"name": "LOWERNAME"
"phone": "1234567899"
}
Call your object like:
let user = {
name: params.name.toLowerCase(),
phone: params.phone
}
You could modify it to suit your situation!

Related

How to convert a nested object to a string indexed object

I am trying to convert a nested object to a string indexed object, so I can use Vue to display all properties in an object. For example:
var obj = {
key1: 'value1',
key2: {
key3: {
key5: 'value5',
key6: 'value6'
},
key4: 'value4'
}
};
Should be convert to this:
var obj = {
'key1': 'value1',
'key2.key3.key5': 'value5',
'key2.key3.key6': 'value6',
'key2.key4': 'value4'
}
I tried to walk recursively through the object, but I didn't figure out how to get the correct index value and return both the index and the object at the same time.
What I've tried so far:
// let result = objConversion(obj)
objConversion (obj) {
let resultObject = {}
// Walk through the first level
for (let index in obj) {
if (obj.hasOwnProperty(index)) {
let extractedObj = getObjNameRecursive(obj[ index ], index)
resultObject = { ...resultObject, ...extractedObj }
}
}
return resultObject
}
getObjNameRecursive (obj, name) {
let resultObject = {}
if (typeof obj === 'object') {
// Dive into an object
for (let index in obj) {
if (obj.hasOwnProperty(index)) {
if (typeof obj[ 'index' ] === 'object') {
resultObject = { ...resultObject, ...getObjNameRecursive(obj[ 'index' ], name + '.' + index) }
} else {
resultObject = {...resultObject, [name + '.' + index]: obj[index]}
}
}
}
} else {
// Simple assign if not an object
resultObject[ name ] = obj
}
return resultObject
}
But this gives the result like:
obj = {
'key1': 'value1',
'key2.key3.key5': [object Object],
'key2.key3.key6': [object Object],
'key2.key4': 'value4'
}
The answer in Convert string to an attribute for a nested object in javascript is very close to what I want. But what I want is to get the string of attributes of a nested object.
Is there any better way to do this?
Thanks.
Try this
function convert(obj, key, result) {
if(typeof obj !== 'object') {
result[key] = obj;
return result;
}
const keys = Object.keys(obj);
for(let i = 0; i < keys.length; i++){
const newKey = key ? (key + '.' + keys[i]) : keys[i];
convert(obj[keys[i]], newKey, result);
}
return result;
}
call it
convert(obj, '', {});

Find the key in an object which contains a particular value in an array

I need to find the key(type:array) which contains a specific string. The actual data would look like as provided below
I tried to inverse the particular object with _.invert(). But doesnt make sense as it would convert the entire array to a string
{
"key1": ['asd','yrt','uyt'],
"key2": ['nbm','inb','oiu']
}
The response desired is that with we can fetch the key_name if an array element is provided.
ie if the input is lets 'asd' we need to be able to say that the key was key1
Take the keys and find the element with includes.
const
find = (object, value) => Object.keys(object).find(k => object[k].includes(value)),
object = { key1: ['asd','yrt','uyt'], key2: ['nbm','inb','oiu'] },
key = find(object, 'asd');
console.log(key);
How often are you going to do this? If only once, then:
data = {
"key1": ['asd','yrt','uyt'],
"key2": ['nbm','inb','oiu']
}
needle = 'oiu'
magicKey = Object.keys(data).filter(key => data[key].includes(needle))
Otherwise you're going to want to make a new dictionary that has your possible needles as keys!
const obj = { key1: ['asd','yrt','uyt'], key2: ['nbm','inb','oiu']}
const keyResult = Object.entries(obj).find(element => element[1].includes('asd'))
console.log(keyResult[0] || 'not found')
It might look like this:
let elementToFind = "asd";
let object = {
"key1": ['asd','yrt','uyt'],
"key2": ['nbm','inb','oiu']
}
let output;
for(let key in object) { // iterate over every key in object
if(object.hasOwnProperty(key)) { // check if we don't try to access one of object's prototype fields etc.
if(object[key].includes(elementToFind)) {
// check if object[key] which is array, contains element we look for
// if so, break the loop to prevent it from further searching
output = key;
break;
}
}
}
let search = 'asd'
let obj = {
"key1": ['asd','yrt','uyt'],
"key2": ['nbm','inb','oiu']
}
Object.keys(obj).find(key => obj[key].indexOf(search) > -1)
If there can be multiple such keys use filter instead of find.
One method would be to iterate over the key/value produced from Object.entries, and return the key where the string is found in the value (array).
const obj = {
key1: ['asd','yrt','uyt'],
key2: ['nbm','inb','oiu']
}
function getKey(obj, str) {
for (let [key, arr] of Object.entries(obj)) {
if (arr.includes(str)) return key;
}
return null;
}
console.log(getKey(obj, 'inb'));
console.log(getKey(obj, 'asd'));
You could write a function that recursively returns the path...
const hasKey = (key, data) => ({}).hasOwnProperty.call(data, key);
const typeOf = value => ({}).toString.call(value).replace(/\[object (\w+)]/, '$1');
const isLeaf = value => ['String', 'Boolean', 'Null', 'Undefined', 'Number', 'Date', 'Function'].includes(typeOf(value));
const needle = 'asd';
const haystack = {
"key1": ['asd1','yrt','uyt'],
"key2": ['nbm','inb','oiu'],
key3: {
key4: ['asd'],
}
};
const find = (needle, haystack, path = []) => {
if (isLeaf(haystack)) {
return needle === haystack && path;
}
for (let [key, value] of Object.entries(haystack)) {
const result = find(needle, value, path.concat(key));
if (result) { return result; }
}
};
console.log('find', find(needle, haystack));

Javascript access and write object sub-value through array of successive keys [duplicate]

This question already has answers here:
Javascript: Get deep value from object by passing path to it as string [duplicate]
(5 answers)
Closed 7 years ago.
How can I get the method getValueThroughPath(object, keysArray) that works like so:
var object = {
key1: {
key2: {
key3: {
key4: "value"
}
}
}
}
getValueThroughPath(object, ['key1', 'key2', 'key3', 'key4']); // = "value" and undefined if wrong path
?
I'm also looking for the setValueThroughPath(object, keysArray) equivalent method.
I use Lodash if this can shorten the solution.
This will walk the object down to the last key. If any key is misspelled or missing, it will return undefined:
function getValueThroughPath(obj, keys) {
while(obj=obj[keys.shift()] || '', keys.length);
return obj || undefined;
}
function setValueThroughPath(obj, keys, val) {
while(keys.length>1) {
obj[keys[0]]= obj[keys[0]] || {};
obj= obj[keys.shift()];
};
obj[keys[0]]= val;
}
var object = {
key1: {
key2: {
key3: {
key4: "value"
}
}
}
}
setValueThroughPath(object, ['this', 'is', 'a', 'test'], 'Eureka!');
setValueThroughPath(object, ['this', 'is', 'a', 'new', 'test'], 'Hallelujah!');
console.log(getValueThroughPath(object, ['key1', 'key2', 'key3', 'key4'])); // "value"
console.log(getValueThroughPath(object, ['key1', 'key2', 'key5', 'key4'])); // undefined
console.log(getValueThroughPath(object, ['this', 'is', 'a', 'test'])); // "Eureka!"
console.log(getValueThroughPath(object, ['this', 'is', 'a', 'new', 'test'])); // "Hallelujah!"
You can iterate through your object properties and get the appropriate value using a function like this:
function getValueThroughPath(object, keys) {
var temp = object;
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (temp.hasOwnProperty(key)) {
temp = temp[key];
console.log(JSON.stringify(temp));
} else {
console.log('Couldnt find key ' + key);
return undefined;
}
}
return temp;
}
You can check the fiddle at http://jsfiddle.net/bx82akj5/ to see it working (open console to check it out! =D)
I used the "hasOwnProperty" method so you don't end up accessing an inexistent property or accessing a property of Object in javascript, so you iterate only through the properties defined in your object.
The function setValueTrhoughPath that you are looking for is pretty much the same (just analogous, of course)

Best way to reset all values in an Javascript object

My javascript object looks something like:
$scope.display = {
current: {
key1: 'value1',
key2: ['a', 'b'],
key3: 'value2'
}
}
Upon some events in my code, I would like to reset these values to undefined like below:
$scope.display = {
current: {
key1: undefined,
key2: [],
key3: undefined
}
}
I use libraries like lodash, however i don't see any function that would perform this.
I know how to do this manually, but I was wondering if there is a "Best practices" way of performing this task.
I would create a helper function returning object structure:
function getDisplayObject() {
return {
current: {
key1: undefined, // or you can omit undefined keys
key2: [],
key3: undefined
}
};
}
$scope.display = getDisplayObject();
So later when you need to reset data you would execute $scope.display = getDisplayObject(); again.
Here is my solution with lodash mapValues function:
var $clearObject = function(value) {
if (_.isString(value)) {
return undefined
};
if (_.isArray(value)) {
return [];
};
};
var $scopeDisplay = {
current: {
key1: 'value1',
key2: ['a', 'b'],
key3: 'value2'
}
};
$scopeDisplay.current = _.mapValues($scopeDisplay.current, $clearObject);
console.log($scopeDisplay);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
You would loop the properties of your object like this
for (var key in current){
if (current.hasOwnProperty(key)){
if (typeof current[key] === 'string'){
current[key] = undefined;
} else if (current[key] instanceof Array) {
current[key] = [];
} // else ??? Not sure how you want to handle other types
}
}
Array check subject to some potential problems described in the comments here
What about this?
// If you just want to reset a simple object
let reset = (obj) => {
Object.keys(obj).map(key => {
if (obj[key] instanceof Array) obj[key] = []
else obj[key] = undefined
})
}
// If you want to reset a complex object
let recursiveReset = (obj) => {
Object.keys(obj).map(key => {
// Test if it's an Object
if (obj[key] === Object(obj[key])) {
recursiveReset(obj[key])
return
}
if (obj[key] instanceof Array) obj[key] = []
else obj[key] = undefined
})
}
// So you can simply use
reset($scope.display.current)
// or
recursiveReset($scope.display)
test link
In my Angular controller, I do the following:
$scope.user = {
firstname: "",
lastname: "",
displayname: "",
email: "",
password: "",
passwordConfirm: ""
};
// default state of the form
$scope.default = angular.copy($scope.user);
/**
* Resets the form to its default state
* #return {void}
*/
$scope.reset = function () {
$scope.user = angular.copy($scope.default);
}
Initially the scope is empty, so I clone it, and whenever it needs reset, simply call a function. However, without knowing the scope of your project, it's hard to determine the best way to handle it.
I did it in AngularJS controller as:
function item_object() {
var list_item = {
ID: '',
Title: '',
LastName: '',
Contact: '',
City: ''
};
return list_item;
}
//Define the object for the item
$scope.Item = item_object();
// Reset product details
$scope.clear = function () {
$scope.Item = item_object();
}
In this way you do not keep a copy of empty or default object. So no extra cost.
There is no built in way. You would need to loop through and set the defaults based on type.
var x = {
current: {
key1: 'value1',
key2: ['a', 'b'],
key3: 'value2'
}
};
_(x.current).forEach(
function(value, key, obj) {
var result = undefined;
if (_.isArray(value)) {
result = [];
}
obj[key] = result;
}
);
console.log(x);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
Basic idea if you have nested objects
var x = {
current: {
key1: 'value1',
key2: ['a', 'b'],
key3: 'value2',
xxxx: {
keyx1: 'valuex1',
keyx2: ['xa', 'xb'],
keyx3: 'valuex2'
}
}
};
function resetObj (obj) {
_(obj).forEach(
function(value, key, objRef) {
var result = undefined;
if (_.isObject(value)) {
resetObj(objRef[key]);
} else {
if (_.isArray(value)) {
result = [];
}
objRef[key] = result;
}
}
);
}
resetObj(x)
console.log(x);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
If you are using Jquery, like it seems you are doing, you can do that:
Preapre an empty template of your object:
var emptyTemplate = {
current: {
key1: undefined,
key2: [],
key3: undefined
}
}
and then run:
$scope.display = $.extend(true, {}, emptyTemplate);
If you want to automate it, define some data binding:
var defaults = {
String: undefined,
Array: [],
bool: false
}
Then loop in your object, like other suggestions:
function resetObj (obj) {
_(obj).forEach(
function(value, key, objRef) {
if (_.isObject(value)) {
resetObj(objRef[key]);
} else {
var myvarType = typeOf value;
objRef[key] = defaults[myvarType];
}
}
);
}
I copied this nesting function from other answer, just to add my two cents.
A good way to deal with this would be to use a class instead of an object literal, like:
class current {
constructor() {
this.key1 = undefined;
this.key2 = [];
this.key3 = undefined;
}
}
And whenever you want to clear all the values you can just create a new instance of this class, like:
$scope.display.current = new current();
function isObject (value) {
return value && typeof value === 'object' && value.constructor === Object;
}
const resetObj = (obj, resetVal) => {
if(!isObject(obj)) return;
for(let i in obj){
if(!obj.hasOwnProperty(i)) continue;
if(!isObject(obj[i])){
obj[i] = resetVal;
}else{
resetObj(obj[i], resetVal);
}
}
};
+++++++++++++++++++++++++Typescript solution+++++++++++++++++++++++++++
private deviceSettingsToReset: RemoteDeviceSetting;
// depp copy of response into deviceSettingsToReset variable which need to use in reset functionality in UI.
this.deviceSettingsToReset = JSON.parse(JSON.stringify(response));
// assign value from original copy.
this.selectedAlgorithm = JSON.parse(JSON.stringify(this.deviceSettingsToReset));

javascript - Add property to object literal and return

I have object literal what I consider as base object:
var obj = {
key1 : 'value1',
key2 : 'value2'
}
and would like to use this object and pass it to function with extention like
myFunction( obj + { key3 : 'value3' } );
// param became:
{
key1 : 'value1',
key2 : 'value2',
key3 : 'value3'
}
or
myFunction( obj + { key2 : 'new value2' } );
// param became:
{
key1 : 'value1',
key2 : 'new value2'
}
+ operator is not correct for it. How I can do it? Is it a way ?
EDIT: Do you want to permanently alter obj? - No, I would like to able to reuse it for next call as base.
With ES2018 or TypeScript 2.1 you can use the object spread syntax.
// properties on the right overwrite properties on the left
// Overwrite properties from obj
myFunction( { ...obj, key3: 'value3' } );
// Don't overwrite properties from obj
myFunction( { key3: 'value3', ...obj } );
With ES2015 you can use Object.assign.
// Object.assign(a, b, c, ..) - copy properties from b to a, then from c to a etc.
// Overwrite properties from obj
myFunction( Object.assign({}, obj, { key3: 'value3' }) );
// Don't overwrite properties from obj
myFunction( Object.assign({ key3: 'value3' }, obj) );
Demo
var obj = { key1: 'value1', key2: 'value2'}
console.log('-- Object Spread --');
console.log({ ...obj, key3: 'value3' });
console.log('overwrite');
console.log({ ...obj, key2: 'NEW2' });
console.log('no overwrite');
console.log({ key2: 'NEW2', ...obj });
console.log('-- Object Assign --');
console.log(Object.assign({ key3: 'value3' }, obj));
console.log('overwrite');
console.log(Object.assign({}, obj, { key2: 'NEW2' }));
console.log('no overwrite');
console.log(Object.assign({ key2: 'NEW2' }, obj));
console.log('-- Original Object unchanged --');
console.log(obj);
If you're okay with altering obj, just change it before you pass it:
var obj = { /* stuff */ };
obj.key3 = 'value3';
myFunction(obj);
Do you want to permanently alter obj? - No, I would like to able to reuse it for next call as base.
Okay, so you need to make a copy of obj, and alter the copy — either before you call myFunction:
var obj = { /* stuff */ };
var extension = {key3: 'value3'};
myFunction($.extend({}, obj, extension));
or pass obj and the "extension" to myFunction:
var obj = { /* stuff */ };
var extension = {key3: 'value3'};
myFunction(obj, extension);
and have myFunction do the work:
function myFunction(base, ext)
{
if (typeof base === 'object' && typeof ext === 'object')
{
base = $.extend({}, base, ext);
}
// rest of the function logic here
}
If you're already (or don't mind) using jQuery, $.extend() will be your best friend for the task.
You could create a function that extends objects nondestructively (not "extend", really, just make a new object from another one), for example:
var oldObj = {name: 'foo'};
function extendNonDestructive(src, newProps) {
function F() {} F.prototype = src;
var newObj = new F;
for (var p in newProps) {
if (newProps.hasOwnProperty(p)) {
newObj[p] = newProps[p]
}
}
return newObj
}
var newObj = extendNonDestructive(oldObj, {lastName: 'bar'}); // Doesn't touch oldObj
Note: You might be interested in Object.create which is way more flexible than the little "function F() {}; F.prototype = src;" in my code, but it's ES5+.
If you wanted to add properties to an existing object and return the new object in one line, you can use a combination of the Object.fromEntries and Object.entries functions:
console.log(
Object.fromEntries(
Object.entries({
t:4,
f:2
})
.concat(
Object.entries({
q:2,
p:9
})
)
)
);
This also works if you want to just modify a single property of an existing object, just, for the new object properties, add the object you want to replace, i.e.:
....concat(Object.entries({t:2}))...
would just modify the t property of the original object.

Categories

Resources