I have an object and for all keys that have a null value I want to replace this null with an empty string (or a dash in my case)?
For example
Obj = {
key1: null,
key2: null,
key3: true,
...
key_n: null
}
Turns into
Obj = {
key1: "-",
key2: "-",
key3: true,
...
key_n: "-"
}
This will work.
const Obj = {
key1: null,
key2: null,
key3: true,
key_n: null
};
for (const key in Obj) {
const val = Obj[key];
if (val === null) {
Obj[key] = "-";
}
}
console.log(Obj);
const obj = {
key1: null,
key2: null,
key3: true,
key_n: null
};
Object
.entries(obj)
.forEach(function ([key, value]) {
if (value === null) {
this[key] = '-';
}
}, obj); // make use of `forEach`'s `thisArg` parameter.
console.log({ obj });
You just have to match whether a key's corresponding value is null or not , if yes then change it to underscore.
Obj = {
key1: null,
key2: null,
key3: true,
key_n: null
}
Object.keys(Obj).map(key=>{
if(!Obj[key])Obj[key] = "_"
})
console.log(Obj)
Related
So lets say I have an object like this:
myObject = {
key1: "foo",
key2: "",
key3: "bar",
key4: "foobar",
key5: undefined
}
And I want an array of the keys, but only if the have a value. i.e. if they're undefined or empty string, I don't want them included in the array.
Currently I'm using Object.keys(myObject) but this gets all the keys including those that are undefined, false or nullable value.
I completely understand I can likely write my own version of the keys method from Object, but I'm wondering if there's an easier way than that.
Filter the entries by whether the key portion of the entry is truthy, then map to the keys:
const myObject = {
key1: "foo",
key2: "",
key3: "bar",
key4: "foobar",
key5: undefined
};
const keys = Object.entries(myObject)
.filter(([, val]) => val)
.map(([key]) => key);
console.log(keys);
You only need to use Array.filter() to remove the keys that have nullable results
const myObject = {
key1: "foo",
key2: "",
key3: "bar",
key4: "foobar",
key5: undefined
};
const keys = Object.keys(myObject)
.filter(key => myObject[key])
console.log(keys);
If all you care about are the truthy keys you can use a somewhat simpler filter than above:
myObject = {
key1: "foo",
key2: "",
key3: "bar",
key4: "foobar",
key5: undefined
}
truthyKeys = Object
.keys(myObject) // array of all keys
.filter(k => myObject[k]) // filter out ones with falsy values
console.log(truthyKeys)
const myObject = {
key1: "foo",
key2: "",
key3: "bar",
key4: "foobar",
key5: undefined
};
const keys = Object.keys(myObject).filter(key => myObject[key]);
This will also cut out other falsy values however, such as 0, NaN, null, false. If you very specifically are guarding against empty strings and undefined:
const myObject = {
key1: "foo",
key2: "",
key3: "bar",
key4: "foobar",
key5: undefined
};
const keys = Object.keys(myObject)
.filter(key => myObject[key] !== '' && myObject[key] !== undefined);
I don't know if there is another way but you can try something like this
myObject = {
key1: "foo",
key2: "",
key3: "bar",
key4: "foobar",
key5: undefined
}
const getValue = (obj) => {
const array = [];
for (const [key, value] of Object.entries(obj)) {
if(value){
array.push(key);
}
}
return array;
}
console.log(getValue(myObject));
let objectWithTruthyKeys = Object.keys(myObject).filter(i => myObject[i]);
Explanation:
Object.keys will get all the keys of the property (including the ones that contain falsy values).
The filter will go through each key in myObject (represented by i). the condition will be true only if the value is truthy, hence, filtering out the keys which contain falsy values.
There's a couple ways to do that. You could use filter:
const myObject = {
key1: "foo",
key2: "",
key3: "bar",
key4: "foobar",
key5: undefined
}
var keysWithValues = Object.keys(myObject).filter(key => myObject[key]);
console.log(keysWithValues);
Or a for loop:
const myObject = {
key1: "foo",
key2: "",
key3: "bar",
key4: "foobar",
key5: undefined
}
var keysWithValues = [];
for (const [key, value] of Object.entries(myObject)) {
if (value) {
keysWithValues.push(key);
}
}
console.log(keysWithValues);
You could also be fancy and extend Object by creating a class. But I believe that would be overkill :D
try it.
myObject = {
key1: "foo",
key2: "",
key3: "bar",
key4: "foobar",
key5: undefined
}
let x= Object.entries(myObject);
for(i=0;i<x.length;i++){
if(x[i][1]!==undefined&&x[i][1]!==""){
console.log(x[i][0])}
}
I have a dynamic object :
input: {
key1: 'text1',
key2: 10000,
key3: 3456,
key4: 'text2',
key5: ['v1','v2','v3'] .....
}
I would like to reset it to
output
{
key1: '',
key2: 0,
key3: 0,
key4: '',
key5: []
.......
}
I didn't find any direct method to do this, I know to do this with looping. I was wondering if we have best method/best practices to acheive output.
You could take Object.assign with an object of the wanted values.
This method does not replace unknown properties. In this case, you need a new object, or you need to delete all propeties in advance.
const
values = { key1: '', key2: 0, key3: 0, key4: '', key5: [] },
input = { key1: 'text1', key2: 10000, key3: 3456, key4: 'text2', key5: ['v1','v2','v3'] };
Object.assign(input, values);
console.log(input);
A dynamic object with deleting own enumerable properties.
const
values = { key1: '', key2: 0, key3: 0, key4: '', key5: [] },
input = { foo: '42', bar: '101', key1: 'text1', key2: 10000, key3: 3456, key4: 'text2', key5: ['v1','v2','v3'] };
Object.keys(input).forEach(Reflect.deleteProperty.bind(null, input));
Object.assign(input, values);
console.log(input);
You can define all the default values in an object, and use the spread operator
let input = {key1:'text1', key2:10000, key3:3456, key4:'text2', key5:['v1','v2','v3']}
const defaultValues = {key1:'', key2:0, key3:0, key4:'', key5:[]}
input = {
...defaultValues
}
console.log(input)
You can loop through all the elements in the object and based on the type of the property we can reset it to default value. Below is the example.
let input = {key1:'text1', key2:10000, key3:3456, key4:'text2', key5:['v1','v2','v3']}
const resetData = (data) => {
let keys = Object.keys(data);
let dataCopy = {};
keys.forEach(key => {
if(Array.isArray(data[key])) {
dataCopy[key] = []
} else if(typeof data[key] === "object") {
dataCopy[key] = {}
} else if(typeof data[key] === "string") {
dataCopy[key] = ""
} else {
dataCopy[key] = 0
}
})
return dataCopy;
}
console.log(resetData(input));
input = {key6: {abc: "123"}, key7: "dummy", key8: [1, 2, 3] }
console.log(resetData(input));
I have an object with multiple keys and values.
I only want to rename some of the keys and not all. With what I do, it is not returning the rest of the key-value pairs in the object:
data = {key1: "value1", key2: "value2", key3: "value3", key4: "value4"};
keyMap = {key1: "firstkey", key2: "secondkey"};
mappedData = Object.keys(keyMap).reduce((obj,k) => Object.assign(obj, { [keyMap[k]]: data[k] }),{});
console.log(mappedData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
How do I get back:
{
firstkey: "value1",
secondkey: "value2",
key3: "value3",
key4: "value4"
}
You could get the entries and replace the keys by checking keyMap and get either the new or take the old key.
let data = { key1: "value1", key2: "value2", key3: "value3", key4: "value4" };
keyMap = { key1: "firstkey", key2: "secondkey" },
mappedData = Object.fromEntries(
Object
.entries(data)
.map(([key, value]) => [key in keyMap ? keyMap[key] : key, value])
);
console.log(mappedData);
Perhaps something like this:
const changeKeys = (keyMap) => (obj) =>
Object .fromEntries (Object .entries (obj) .map (([k, v]) => [keyMap[k] || k, v]))
const data = {key1: "value1", key2: "value2", key3: "value3", key4: "value4"};
const keyMap = {key1: "firstkey", key2: "secondkey"};
console .log(
changeKeys (keyMap) (data)
)
Using Object.entries and Object.fromEntries with a map or other transform in between solves all sorts of Object manipulation problems.
If Object.fromEntries is not available for your environment, it's easy to shim.
Here's your code with a little update:
data = {key1: "value1", key2: "value2", key3: "value3", key4: "value4"};
keyMap = {key1: "firstkey", key2: "secondkey"};
mappedData = Object.keys(data).reduce((obj,k) => Object.assign(obj, { [keyMap[k] || k]: data[k] }),{});
console.log(mappedData);
You could do it in one pass with a for loop
data = {key1: "value1", key2: "value2", key3: "value3", key4: "value4"};
keyMap = {key1: "firstkey", key2: "secondkey"};
const isDefined = x => typeof x !== 'undefined'
const renameKeys = o => {
const newObj = {}
for (const key in o) {
if (isDefined(keyMap[key])) {
newObj[keyMap[key]] = o[key]
} else {
newObj[key] = o[key]
}
}
return newObj
}
console.log(
renameKeys(data)
)
I would loop over the data and see if a key exists. If it does use it, if not use the original key.
var data = {
key1: "value1",
key2: "value2",
key3: "value3",
key4: "value4"
};
var keyMap = {
key1: "firstkey",
key2: "secondkey"
};
const updated = Object.entries(data).reduce((obj, [key, value]) => {
const updatedKey = keyMap[key] || key
obj[updatedKey] = value
return obj
}, {})
console.log(updated);
The problem is that your accumulator in your reduce function is a new, empty object, and you're only iterating over the keys you want to change.
There are a lot of ways to do what you're trying to do. I personally find reduce confusing to parse, so I'd skip that and do something like this:
const data = {key1: "value1", key2: "value2", key3: "value3", key4: "value4"};
const keyMap = {key1: "firstkey", key2: "secondkey"};
const mappedData = {};
for(const key of Object.keys(data)){
// Use the renamed key if it exists, else fall back on the original key
mappedData[ keyMap[key] || key ] = data[ key ];
}
console.log(mappedData);
You could apply the same sort of logic to the reduce if you really wanted to do it that way, by iterating over the original data instead of the keymap:
const data = {key1: "value1", key2: "value2", key3: "value3", key4: "value4"};
const keyMap = {key1: "firstkey", key2: "secondkey"};
mappedData = Object.keys(data).reduce((obj,k) => Object.assign(obj, { [keyMap[k] || k]: data[k] }),{});
console.log(mappedData);
Question In JavaScript Form
I have an object like this:
const obj1 = {key1: value1, key2: value2, key3: value3, ...}
To change value of key1 (can be any key), this is my way:
const obj2 = {...obj1, key1: newValue}
I want to set all keys to some newValue, how to do it without mutation?
Wanted Output:
{key1: newValue, key2: newValue, key3: newValue, ...}
Question In Redux Form
I have my state like this:
{
key1: value1,
key2: value2,
key3: value3,
// ...
}
To change one value, I am doing like this in my reducer:
return {
...state,
[action.key]: action.value
}
But how to change value of all the keys if I give some value through my action.value? I want my next state like this:
{
key1: newValue,
key2: newValue,
key3: newValue,
// ...
}
You need to loop over keys, and create a new object using say reduce
const obj = {
key1: 1,
key2: 2,
key3: 3
}
const value = 0;
const updated = Object.keys(obj).reduce((acc, key) => (acc[key] = value, acc), {})
console.log(obj, updated)
Just for fun some proxy magic (do not use for production)
const obj = {
key1: 1,
key2: 2,
key3: 3
}
const value = 0
const updated = { ...new Proxy(obj, {
keys() {
return Object.keys(obj)
},
get() {
return value
}
})
}
console.log(obj, updated)
I receive an object and each time it different quantity of strings different every time
Object {
key_id: 7,
key1: "String1, String2",
key2: "String1, String2, String3",
key3: "String1, String2",
key4: "String1, String2";
…
}
I want to receive
Array = [{key_id: 7, key1: "String1", key1: "String2" ...}]
or
Array = [{key_id: 7, key1: "String1", "String2" ...}]
I need that to make this strings separated to make from them separated links.
I am making it on ReactJs with JSX/Babel ES6
Use Object#entries to convert to an array of [key, value] pairs, and Array#map them:
const data = {
key_id: 7,
key1: "String1, String2",
key2: "String1, String2, String3",
key3: "String1, String2",
key4: "String1, String2"
};
const result = Object.entries(data).map(([key, value]) => ({
[key]: typeof value === 'string' ? value.split(', ') : value
}));
// an array with multiple objects
console.log(result);
// A single object:
console.log(Object.assign({}, ...result));
Note that Object#entries is not part of ES6, and is not supported by IE and Edge.
EDIT: Updated the code to change each property to array element.
let data = {
key_id: 7,
key1: "String1, String2",
key2: "String1, String2, String3",
key3: "String1, String2",
key4: "String1, String2"
};
Object.keys(data).forEach(function(key) {
data[key] = typeof data[key] === 'string' ? data[key].split(', ') : data[key];
});
console.log(data);