NodeJS Object Casting with defaults and removing extra keys - javascript

Assuming somewhere in NodeJS backend code, we have this object:
{
name : "foo"
secret : "bar"
}
We want to return this object as JSON in response of an HTTP request, but, we don't want it to have the secret, i.e. the return object must be:
{
name : "foo"
}
Assume we are using the latest NodeJS and we can use any 3rd party npm package.
Bonus for default params, for example, what if we want the returned object to always include "age", if it's not present, then set it to 0
{
name : "foo"
age : 0
}
EDIT: To add more context, I am not just trying to remove one particular elements, there could be more unwanted elements:
{
name : "foo"
secret1 : "bar"
secret2 : "bar"
secret3 : "bar"
someSecretThatIdontKnowTheirNameYet : "bar"
}
I just have a prototype, or class, or whatever which says:
{
name: String, required
age: Number, required
}
I am trying to figure what this unknown thing above is. Looking for something like:
cleanedUpObject = clean(rawObject, prototypeOrClassOrSomeOtherThing)

You can use a function, and destructure the object. You can set default values on specific properties. Then you can return a new object with the properties you want.
const formatResponse = ({ name, age = 0 }) => ({
name,
age,
});
const data = {
name : "foo",
secret1 : "bar",
secret2 : "bar",
secret3 : "bar",
someSecretThatIdontKnowTheirNameYet : "bar"
};
console.log(formatResponse(data));
Another option is to reduce the model, and include only the properties that exist in the model. If a property is not found on the object, take the default from the model.
const model = {
name: 'baz',
age: 0
}
const formatResponse = (o) =>
Object.entries(model)
.reduce((r, [k, v]) => {
r[k] = k in o ? o[k] : v;
return r;
}, {});
const data = {
name: "foo",
secret1: "bar",
secret2: "bar",
secret3: "bar",
someSecretThatIdontKnowTheirNameYet: "bar"
};
console.log(formatResponse(data));

Just remove private fields from your data and append default value:
const BLACK_LIST_FIELDS = ["secret"];
const DEFAULT_FIELDS_MAP = {
age: 0,
};
function getResponse(data) {
let safeRes = Object.assign({}, data);
BACK_LIST_FIELDS.forEach((key) => delete safeRes[key]);
Object.keys(DEFAULT_FIELDS_MAP).forEach((key) => {
if (!safeRes[key]) {
safeRes[key] = DEFAULT_FIELDS_MAP[key];
}
});
return safeRes;
}
const data = {
name : "foo",
secret : "bar",
};
console.log(getResponse(data));
Result: { name: 'foo', age: 0 }

best two options I can think of:
toJSON
const o = {
name : "foo",
secret : "bar",
toJSON() {
return {
name: this.name
}
}
}
console.log(JSON.stringify(o));
you can return what you want from toJSON, for more info read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior
Symbol
const secret = Symbol('secret');
const o = {
name : "foo",
[secret]: "bar"
};
console.log(JSON.stringify(o));
console.log(o[secret]);
for more info on Symbol read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol

Here’s what I understand from your question:
you have an Object that defines the keys and types of your expected result.
You call this prototypeOrClassOrSomeOtherThing. Let’s call this definition, for short (since boh prototype and class have a defined meaning in JS)
you have another Object that contains a certain function result. Let’s call this input.
you want an Object that consists of only those keys and values from input that are defined in definition.
In case input does not contain a key/value that's defined in definition, use a reasonable default value based on the type defined in definition.
Strategy
we’ll write a function defaultsFromDefinition that creates an object with default values as defined by definition
we then call this function to start out with an object of default values, cleanedUpObject
next we replace this object's values with values from input if and only if input has a matching key/value pair
profit
Code
function defaultsFromDefinition(
definition,
defaultsByType = { String: '', Number: 0 })
{
return Object
.entries(definition)
.reduce((result, [key, type]) => ({
...result,
[key]: defaultsByType[type.name]
}), {})
}
function clean(input, definition) {
const cleanedUpObject = defaultsFromDefinition(definition)
return Object
.keys(cleanedUpObject)
.filter(key => input[key] !== undefined)
.reduce((result, key) => ({
...result,
[key]: input[key]
}), cleanedUpObject)
}
// ---- Test ----
const rawObject = {
name : "foo",
secret1 : "bar",
secret2 : "bar",
secret3 : "bar",
someSecretThatIdontKnowTheirNameYet : "bar"
}
const definition = {
name: String,
age: Number
}
const cleanedUpObject = clean(rawObject, definition)
console.log(cleanedUpObject)

Related

How to check if an object has other than specific properties

I have an object obj which has n number of possible properties
lets say some of them are known,
const someKnownProps = ["props.abc", "xyz"]; // or more
I want to know if obj has other than known properties in it.
To clarify:
obj can look like this:
obj = {
props: {
abc: {
def: 1
},
ghi: {
jkl: 2
}
},
xyz: 3
}
Doing Object.keys only return first level children,
in this case it will return props not props.abc
You can use Object.keys to get all keys and filter the keys which aren't included in the someKnownProps array.
const obj = {
"props.abc": 1,
"xyz": 2,
"three": 3,
"four": 4,
}
const someKnownProps = ["props.abc", "xyz"]; // or more
const unknownKeys = Object.keys(obj).filter(key => !someKnownProps.includes(key))
console.log(unknownKeys)
There are two (unrelated) tasks involved in this question:
Traversal of an object's properties
Comparison of a set of traversed object properties to a list of strings representing dot-notation-formatted object property accessors
While I'm sure the former has been previously discussed on SO, I'll provide an implementation of such an algorithm below in order to address the details of this question.
This is essentially a specific case of recursion where each cycle starts with these inputs:
an object
a dot-notation-formatted path
a Set of existing such paths
The code below includes inline comments explaining what's happening, and there are some console.log statements at the end to help you visualize some example results based on the data in your question. If something is unclear after reviewing the code, feel free to leave a comment.
'use strict';
/** #returns whether value is a non-null, non-array object */
function isObject (value) {
return value !== null && typeof value === 'object' && !Array.isArray(value);
}
/** #returns the enumerable (optionally including inherited) keys of an object */
function getKeys (obj, includeInherited = false) {
if (!includeInherited) return Object.keys(obj);
const keys = new Set();
let o = obj;
while (o !== null) {
for (const key of Object.keys(o)) keys.add(key);
o = Object.getPrototypeOf(o);
}
return [...keys];
}
/**
* #returns an array of strings representing all traversible branches
* of child objects, each formatted as a combined path of dot-notation
* property accessors
*/
function findObjectPaths (
obj,
{
includeInherited = false,
currentPath = '',
paths = new Set(),
skipReturn = false,
} = {},
) {
for (const key of getKeys(obj, includeInherited)) {
// Append the current dot-notation property accessor
// to the existing path of this object:
const path = `${currentPath}.${key}`;
// Add it to the set:
paths.add(path);
const o = obj[key];
// Recurse if the child value is an object:
if (isObject(o)) {
findObjectPaths(o, {
includeInherited,
currentPath: path,
paths,
skipReturn: true,
});
}
}
// If this is not a sub-cycle (it's the top-level invocation), then convert
// the set to an array and remove the first "." from each string
if (!skipReturn) return [...paths].map(p => p.slice(1));
}
// Use:
const obj = {
props: {
abc: {
def: 1,
},
ghi: {
jkl: 2,
},
},
xyz: 3,
};
let someKnownProps = ['props.abc', 'xyz'];
let objectPaths = findObjectPaths(obj);
let hasOtherProps = objectPaths.some(path => !someKnownProps.includes(path));
console.log(hasOtherProps); // true
// An example of all of the paths in the object above:
someKnownProps = [
'props',
'props.abc',
'props.abc.def',
'props.ghi',
'props.ghi.jkl',
'xyz',
];
objectPaths = findObjectPaths(obj);
hasOtherProps = objectPaths.some(path => !someKnownProps.includes(path));
console.log(hasOtherProps); // false
// Finally, comparing the results of inherited vs non-inherited enumeration:
const objWithoutOwnProps = Object.create({
props: {
abc: {
def: 1,
},
ghi: {
jkl: 2,
},
},
xyz: 3,
});
console.log(
'Non-inherited props:',
findObjectPaths(objWithoutOwnProps),
);
console.log(
'Inherited props:',
findObjectPaths(objWithoutOwnProps, {includeInherited: true}),
);
Similar to what Mina said:
let obj = {one: 1, two: 2, three: 3};
let knownKeys = ['one', 'two'];
for (let key in obj) {
if (!knownKeys.includes(key)) {
console.log(key);
}
}

Merging values from an array of strings into a nested object in javascript

I want to merge values from an array into a static nested object. The array containing the values is something like this,
['name=ABC XYZ', 'hobbies=[M,N,O,P]', 'profession=S', 'age=27']
and the object in which the values has to be merged is,
const person = {
details_1: {
name: null,
hobbies: null,
profession: null
},
details_2: {
age: null
}
};
I want my output object to look like below,
const updated_person = {
details_1: {
name: 'ABC XYZ',
hobbies: [M,N,O,P],
profession: 'S'
},
details_2: {
age: 27
}
};
Thanks a lot for your help!
I made another solution with a different approach.
Here I used an interface weher I described the desired data structure.
In the second part the string array is tranformed into key and value pairs. Thereform are filtered the keys of interface and added into an empty object literal.
const data = ["name=ABC XYZ", "hobbies=[M,N,O,P]", "profession=S", "age=27"];
const dataInterface = {
details_1: { name: null, hobbies: null, profession: null },
details_2: { age: null },
};
function orederData(arr) {
const record = arr.map((item) => {
let [key, value] = item.split("=");
if (value[0] === "[" && value[value.length - 1] === "]") {
value = value.slice(1, value.length - 1).split(",");
}
return { key, value };
});
const dataBlock = {};
Object.keys(dataInterface).map((detail) => {
dataBlock[detail] = {};
Object.keys(dataInterface[detail]).forEach((dataKey) => {
dataBlock[detail][dataKey] = record.filter((record) => {
return record.key === dataKey;
})[0].value;
});
});
return dataBlock;
}
const orderedData = orederData(data);
console.log(orderedData);
You can simply achieve this by iterating the input array.
const arr = ['name=ABC XYZ', 'hobbies=[M,N,O,P]', 'profession=S', 'age=27'];
const person = {
details_1: {},
details_2: {}
};
arr.forEach(item => {
(item.split('=')[0] !== 'age') ? person.details_1[item.split('=')[0]] = item.split('=')[1] : person.details_2[item.split('=')[0]] = item.split('=')[1]
});
console.log(person);
There is no way to cleanly merge an unstructured array into a structured object such that the array values end up in the appropriately keyed person properties.
javascript does provide the assign() function that merges objects but for YOUR requirements your source data needs to be an object similarly structured and not an array.
so this:
['name=ABC XYZ', 'hobbies=[M,N,O,P]', 'profession=S', 'age=27']
would need to become this:
const source= [{details_1: {"name":"ABC XYZ", "hobbies":"[M,N,O,P]", "profession":"S"}, details_2: {"age":"27"}}]
such that a call to Object.assign():
const new_person = Object.assign(person, source[0]);
fills this
const person = {
details_1: {
name: null,
hobbies: null,
profession: null
},
details_2: {
age: null
}
};
properly, though you may need to clone or instantiate and empty person first.
or, if person is an Object you could have a fill() method that knows what to do with the array data.

Extract object name as String from an object in JavaScript

I have an object where its values are other objects
I would like to extract the name of the object by its parent key as a string, e.g., (input, expected output) = ('home', 'someObj), ('anotherOne', 'anotherObj').
So far I tried the following, but it returns [object Object].
I also tried JSON.stringify(data[key].key1) but does not return what I want. Is there a way to achieve this?
const someObj = {
something: 'la'
}
const anotherObj = {
something: 'be'
}
const data = {
'home': {
key1: someObj
},
'anotherOne': {
key1: anotherObj
}
}
console.log(data)
const key = 'home'
const output = `${data[key].key1}`
console.log(output) // expected output: 'someObj'
Javascript objects don't have names. You'd have to take care yourself and probably add a 'name' field where you set an identifier on an object instance.
You hope, that the 'name' of the object could be like the name of the variable that you assign it to. But that's not true. There is zero connection between the object instance and the variable name.
The problem is that you are assigning the variable value and not its name. Because JS compiler will not keep track of the variable name that it used to assign values to
so,
const someObj = {
something: 'la'
}
const anotherObj = {
something: 'be'
}
const data = {
'home': {
key1: someObj
},
'anotherOne': {
key1: anotherObj
}
}
JS compiles it as
const data = {
'home': {
key1: {
something: 'la' // Doesn't keep track of the original variable name used to assign value.
}
},
'anotherOne': {
key1: {
something: 'be'
}
}
}
And when you fetch data[key].key1. it returns {something: 'la'} which is an object and when you use string template literal `${data[key].key1}`. It typecast it into string as
`${{}}` // Outputs "[object Object]"
So, you need to store the variable names as string
const someObj = {
something: 'la'
}
const anotherObj = {
something: 'be'
}
const data = {
'home': {
key1: 'someObj'
},
'anotherOne': {
key1: 'anotherObj'
}
}
console.log(data)
const key = 'home'
const output = `${data[key].key1}`
console.log(output) // output: 'someObj'
This code will work
You need to set the variable name as string.

_.assign only if property exists in target object

My need is to do something like an _.assign, but only if the target object already has the property being assigned. Think of it like the source objects may have some properties to contribute, but also some properties that I don't want to mix in.
I haven't ever used _.assign's callback mechanism, but tried the following. It 'worked', but it still assigned the property to the dest object (as undefined). I don't want it to assign at all.
_.assign(options, defaults, initial, function (destVal, sourceVal) {
return typeof destVal == 'undefined' ? undefined : sourceVal;
});
I wrote the following function to do this, but wondering if lodash already has something baked in that is more elegant.
function softMerge (dest, source) {
return Object.keys(dest).reduce(function (dest, key) {
var sourceVal = source[key];
if (!_.isUndefined(sourceVal)) {
dest[key] = sourceVal;
}
return dest;
}, dest);
}
You could take just the keys from the first object
var firstKeys = _.keys(options);
Then take a subset object from the second object, taking only those keys which exist on the first object :
var newDefaults = _.pick(defaults, firstKeys);
Then use that new object as your argument to _.assign :
_.assign(options, newDefaults);
Or in one line :
_.assign(options, _.pick(defaults, _.keys(options)));
Seemed to work when I tested it here : http://jsbin.com/yiyerosabi/1/edit?js,console
Here is a immutable deep version, I call it "merge that retains the shape", in TypeScript that uses lodash:
function _mergeKeepShapeArray(dest: Array<any>, source: Array<any>) {
if (source.length != dest.length) {
return dest;
}
let ret = [];
dest.forEach((v, i) => {
ret[i] = _mergeKeepShape(v, source[i]);
});
return ret;
}
function _mergeKeepShapeObject(dest: Object, source: Object) {
let ret = {};
Object.keys(dest).forEach((key) => {
let sourceValue = source[key];
if (typeof sourceValue !== "undefined") {
ret[key] = _mergeKeepShape(dest[key], sourceValue);
} else {
ret[key] = dest[key];
}
});
return ret;
}
function _mergeKeepShape(dest, source) {
// else if order matters here, because _.isObject is true for arrays also
if (_.isArray(dest)) {
if (!_.isArray(source)) {
return dest;
}
return _mergeKeepShapeArray(dest, source);
} else if (_.isObject(dest)) {
if (!_.isObject(source)) {
return dest;
}
return _mergeKeepShapeObject(dest, source);
} else {
return source;
}
}
/**
* Immutable merge that retains the shape of the `existingValue`
*/
export const mergeKeepShape = <T>(existingValue: T, extendingValue): T => {
return _mergeKeepShape(existingValue, extendingValue);
}
And a simple test to see how I vision such merge should work:
let newObject = mergeKeepShape(
{
a : 5,
// b is not here
c : 33,
d : {
e : 5,
// f is not here
g : [1,1,1],
h : [2,2,2],
i : [4,4,4],
}
},
{
a : 123,
b : 444,
// c is not here
d : {
e : 321,
f : 432,
// g is not here
h : [3,3,3],
i : [1,2],
}
}
);
expect(newObject).toEqual({
a : 123,
// b is not here
c : 33,
d : {
e : 321,
// f is not here,
g : [1,1,1],
h : [3,3,3],
i : [4,4,4]
}
});
I used seamless-immutable myself in the test, but didn't see a need to put it in this answer.
I hereby place this in the Public Domain.
Another way to accomplish this is by combining _.mapObject with _.has
_.mapObject(object1, function(v, k) {
return _.has(object2, k) ? object2[k] : v;
});
Explanation:
Traverse all key/value pairs of object1 using _.mapObject
Using _.has, check if property name k also exists in object2.
If it does, copy the value assigned to key object2's k back to object1, else, just return the existing value of object1 (v).
Plunkr
Following #svarog's answer I came up with this (lodash version 4.17.15):
const mergeExistingProps = (target, source) => _.mapValues(target, (value, prop) => _.get(source, prop, value));
I recently have the same need in my personal project, I need to fill the value from one object(SOURCE) to another object(TARGET) but don't expand its property. Also, some additional requirements should be met:
Any property with a null value in the source will not update to the target;
Any value from the source can be updated into target if such property in target has null value.
The property that holds an array in the target will be loaded based on data from the source, but all entries of the array will remain the same as the target array (so an empty array in the target will not get any data since the item has no property)
Property of the target holding a 2-d array (array has another array as its item) will not be updated, since the meaning of merging two 2-d arrays with a different shape is not clear to me.
Below is an example (Detailed explained in the code):
Assume you have a resume object holding all the data about you, you want to fill the data into the company's application form (also an object). You want the result to have the identical shape of the application form since the company doesn't care about other things, then you can think your resume is SOURCE and the application form is TARGET.
Note that the "additional" field in TARGET is null, which means anything can be updated here based on SOURCE data (As rule #2)
The console output is in JSON format, copy it to some JSON to JS-OBJ converter such as
https://www.convertsimple.com/convert-json-to-javascript/
to have a better view
const applicationForm = {
name: 'Your Name',
gender: 'Your Gender',
email: 'your#email.com',
birth: 0,
experience: [ // employer want you list all your experience
{
company: 'Some Company',
salary: 0,
city: ['', '', ''], // list all city worked for each company
}
],
language: { // employer only care about 2 language skills
english: {
read: false,
write: false,
speak: 'Speak Level'
},
chinese: {
read: false,
write: false,
speak: 'Speak Level'
}
},
additional: null // add anything you want the employer to know
}
const resume = {
name: 'Yunfan',
gender: 'Male',
birth: 1995,
phone: '1234567',
email: 'example#gmail.com',
experience: [
{
company: 'Company A',
salary: 100,
city: ['New York', 'Chicago', 'Beijing'],
id: '0001',
department: 'R&D'
},
{
company: 'Company B',
salary: 200,
city: ['New York'],
id: '0002',
department: 'HR'
},
{
company: 'Company C',
salary: 300,
city: ['Tokyo'],
id: '0003',
}
],
language: {
english: {
read: true,
write: true,
speak: 'Native Speaker'
},
chinese: {
read: true,
write: false,
speak: 'HSK Level 3'
},
spanish: {
read: true,
write: true,
speak: 'Native Speaker'
}
},
additional: {
music: 'Piano',
hometown: 'China',
interest: ['Cooking', 'Swimming']
}
}
function safeMerge(source, target) {
// traverse the keys in the source object, if key not found in target or with different type, drop it, otherwise:
// 1. Use object merge if the value is an object (Can go deeper inside the object and apply same rule on all its properties)
// 2. Use array merge if value is array (Extend the array item from source, but keep the obj format of target)
// 3. Assign the value in other case (For other type, no need go deeper, assign directly)
for (const key in source) {
let value = source[key]
const targetValueType = typeof target[key]
const sourceValueType = typeof value
// if key not found in target or type not match
if (targetValueType === 'undefined' || targetValueType !== sourceValueType) {
continue // property not found in target or type not match
}
// for both type in object, need additional check
else if (targetValueType === 'object' && sourceValueType === 'object') {
// if value in target is null, assign any value from source to target, ignore format
if (target[key] === null) {
target[key] = source[key]
}
// if value in target is array, merge the item in source to target using the format of target only if source value is array
else if (Array.isArray(target[key]) && Array.isArray(value)) {
target[key] = mergeArray(value, target[key])
}
// if value in target is 'real' object (not null or array)', use object merge to do recurring merge, keep target format
else if (!Array.isArray(target[key])){
if (!Array.isArray(value) && value !== null) {
safeMerge(value, target[key])
}
}
}
// if target value and source value has same type but not object, assign directly
else if (targetValueType === sourceValueType) {
target[key] = value
}
}
}
function mergeArray(sourceArray, targetArray) {
// the rule of array merge need additional declare, assume the target already have values or objects in save format in the property<Array>,
// otherwise will not merge item from source to target since cannot add item property,
// NOTE: the item in target array will be totally overwrite instead of append on the tail, only the format will be keep,
// so the lenth of this property will same as source, below is a example:
// target = [{a: 1, b: 2}, {a: 3, b: 4}] // Must in same format, otherwise the first one will be standard
// source = [{a: 5, b: 6, c: 7}]
// mergeArray(source, target) => [{a: 5, b: 6}] // use format of target, but data from source
// double check both of values are array
if (!Array.isArray(sourceArray) || !Array.isArray(targetArray)) {
return
}
// if target array is empty, don't push data in, since format is empty
if (targetArray.length === 0) {
return
}
let resultArray = [] // array to save the result
let targetFormat = targetArray[0]
let targetArrayType = typeof targetArray[0]
// assign value from source to target, if item in target array is not object
if (targetArrayType !== 'object'){
sourceArray.forEach((value) => {
// assign value directly if the type matched
if (targetArrayType === typeof value) {
resultArray.push(value)
}
})
}
// if the item in target is null, push anything in source to target (accept any format)
else if (targetArray[0] === null) {
sourceArray.forEach((value) => {
resultArray.push(value)
})
}
// if the item in target is array, drop it (the meaning of merge 2-d array to a 2-d array is not clear, so skip the situation)
else if (!Array.isArray(targetArray[0])){
// the item is a 'real' object, do object merge based on format of first item of target array
sourceArray.forEach((value) => {
safeMerge(value, targetFormat) // data in targetFormat keep changing, so need to save a independent copy to the result
resultArray.push(JSON.parse(JSON.stringify(targetFormat)))
})
}
else {
console.log('2-d array will be skipped')
}
// replace the value of target with newly built array (Assign result to target array will not work, must assign outside)
return resultArray
}
safeMerge(resume, applicationForm)
console.log(JSON.stringify(applicationForm))

Is there any way to use a numeric type as an object key?

It seems that when I use a numeric type as a key name in an object, it always gets converted to a string. Is there anyway to actually get it to store as a numeric? The normal typecasting does not seem to work.
Example:
var userId = 1;
console.log( typeof userId ); // number
myObject[userId] = 'a value';
console.dir(myObject);
Dir Output:
{
'1': 'a value'
}
What I want is this:
{
1: 'a value'
}
Advice?
No, this is not possible. The key will always be converted to a string. See Property Accessor docs
Property names must be strings. This means that non-string objects cannot be used as keys in the object. Any non-string object, including a number, is typecasted into a string via the toString method.
> var foo = {}
undefined
> foo[23213] = 'swag'
'swag'
> foo
{ '23213': 'swag' }
> typeof(Object.keys(foo)[0])
'string'
In an object, no, but I have found Map extremely useful for this application. Here is where I have used it for numeric keys, a key-based event.
onKeydown(e) {
const { toggleSidebar, next, previous } = this.props;
const keyMapping = new Map([
[ 83, toggleSidebar ], // user presses the s button
[ 37, next ], // user presses the right arrow
[ 39, previous ] // user presses the left arrow
]);
if (keyMapping.has(e.which)) {
e.preventDefault();
keyMapping.get(e.which)();
}
}
Appears to be by design in ECMA-262-5:
The Property Identifier type is used to associate a property name with a Property Descriptor. Values of the Property Identifier type are pairs of the form (name, descriptor), where name is a String and descriptor is a Property Descriptor value.
However, I don't see a definite specification for it in ECMA-262-3.
Regardless, I wouldn't attempt to use non-strings as property names.
you can use, Map if you want different datatype as keys
const map1 = new Map();
map1.set(1,3)
map1.set('1','string')
// expected output: 3
console.log(map1.get(1)) //output 3;
console.log(map1.get('1')) //output 'string';
Here is the solution. Please tell me the environmental setups if this is not working
const screens = {
"768": "large",
"200": "small"
}
const keys = Object.keys(screens).map(key => parseInt(key))
// OR Number(key)
console.log(keys) // Output [200, 768]
Do we need something like this?
var userId = 1;var myObject ={};
console.log( typeof userId ); // number
myObject[userId] = 'a value';
console.dir(myObject);
Console:
Object
1
:
"a value"
You can't, but you can always convert keys to a numbers
const data = { 15: "value", name: "Apple" };
const result = Object.keys(data) // get keys as an array
.map((item) => {
return parseInt(item); // convert to integer number
})
.filter((item) => !isNaN(item)); // remove non number elements
console.log(result); //Output: [15]
const a = {
'1': 'a value'
}
//by using a + before any string value it will convert(parse) that into a number
const b = Object.key(a);
console.log(+b); //parse
console.log(typeof b); //number
Per Mozilla:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax[Spread syntax]1
let obj1 = { foo: 'bar', x: 42 };
let obj2 = { foo: 'baz', y: 13 };
const merge = ( ...objects ) => ( { ...objects } );
let mergedObj1 = merge (obj1, obj2);
// Object { 0: { foo: 'bar', x: 42 }, 1: { foo: 'baz', y: 13 } }
let mergedObj2 = merge ({}, obj1, obj2);
// Object { 0: {}, 1: { foo: 'bar', x: 42 }, 2: { foo: 'baz', y: 13 } }
Just order the items before hand and you should get the result you want.
So for your case:
const merge = (...objects) => ({...objects});
//An object with numeric keys
const values = ["a value", "another value", "and another value"];
let merged = merge(...values);
console.log(merged);
You can try this:
arr = {}
function f(a,b,c) {
arr = arguments
}
f("*","#","_")
console.log(arr)
//returns Object { 0: "*", 1: "#", 2: "_" }```
In JavaScript, numerical strings and numbers are interchangeable, so
myObject[1] == myObject['1']
If you really want number to be the key for an object, you might want an array (i.e. created with new Array() or []).

Categories

Resources