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);
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])}
}
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 have a Java Script Object Like this, It has Property and Value.
var obj = {
key1: 'value1',
key2: 'value2',
key3: 'value3',
key4: 'value4'
}
how can I convert that into this format, Property into another property and value into another property and Want as array.
var obj = [
{
SettingTaget: 'key1'
SettingValue: 'value1'
}
{
SettingTaget: 'key2'
SettingValue: 'value2'
}
{
SettingTaget: 'key3'
SettingValue: 'value3'
}
{
SettingTaget: 'key4'
SettingValue: 'value4'
}
}
Loop your obj and create one array and push object into array.
var obj = {
key1: 'value1',
key2: 'value2',
key3: 'value3',
key4: 'value4'
};
var array_obj = [];
for( var key in obj){
array_obj.push({SettingTaget:key,SettingValue:obj[key]});
}
console.log(array_obj);
var obj = {
key1: 'value1',
key2: 'value2',
key3: 'value3',
key4: 'value4'
}
var newObjArray =[];
for(var x in obj){
newObjArray.push({
SettingTarget:x,
SettingValue:obj[x]
});
}
You can achieve it by this way:
var obj = {
key1: 'value1',
key2: 'value2',
key3: 'value3',
key4: 'value4'
};
var obj1 = [];
for(var i in obj){
obj1[obj1.length] = {"SettingTaget":i, "SettingValue":obj[i]}
}
console.info(obj1);
I prefer the use of Object.keys(obj) instead of for(key in obj) because for more complex objects you need to check the hasOwnProperty in this for-loop
var obj = {
key1: 'value1',
key2: 'value2',
key3: 'value3',
key4: 'value4'
};
var newObjArray = Object.keys(obj).map(function(key)
{
return {
'SettingTarget': key,
'SettingValue': obj[key]
};
});
console.log(newObjArray);
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);
I have an array of objects and I want to get a new array with objects that will have only some of the initial values.
var obj = [{
key1: 'someValue',
key2: 'someValue',
key3: 'someValue'
}, {
key1: 'someValue2',
key2: 'someValue2',
key3: 'someValue2'
}]
I am looking something like Underscore's _.pluck but for more than one values that will give me as a result.
[{
key1: 'someValue',
key2: 'someValue'
}, {
key1: 'someValue2',
key2: 'someValue2'
}]
If there are multiple items in object and you want to only keep few, you can use pick.
_.map(arr, o => _.pick(o, ['key1', 'key2']))
Demo
You can use map with omit.
_.map(arr, o => _.omit(o, 'key3'))
Demo
This is fairly easy with JavaScript's built-in map:
Using an ES2015 arrow function:
var newArray = initialArray.map(e => ({key1: e.key1, key2: e.key2}));
var initialArray = [
{key1: 'someValue', key2: 'someValue', key3: 'someValue'},
{key1: 'someValue2', key2: 'someValue2', key3: 'someValue2'}
];
var newArray = initialArray.map(e => ({key1: e.key1, key2: e.key2}));
document.body.innerHTML = "<pre>" + JSON.stringify(newArray, null, 2) + "</pre>";
Using an old-style function:
var newArray = initialArray.map(function(entry) {
return {key1: entry.key1, key2: entry.key2};
});
var initialArray = [
{key1: 'someValue', key2: 'someValue', key3: 'someValue'},
{key1: 'someValue2', key2: 'someValue2', key3: 'someValue2'}
];
var newArray = initialArray.map(function(entry) {
return {key1: entry.key1, key2: entry.key2};
});
document.body.innerHTML = "<pre>" + JSON.stringify(newArray, null, 2) + "</pre>";
map calls the callback once for each entry in an array, and builds a new array out of the values you return from the callback. So in the above, we're returning new objects with just key1 and key2.
(I renamed obj to initialArray because while arrays are objects, I wanted to emphasize that we were dealing with an array.)