There are quite a few similar questions but I couldn't get their answers to work.
let obj = {};
const key;//a string
const value;//a string
obj[key].push(value);
Obviously this doesn't work but I don't know how to do this. I want it to add a new key and value if it doesn't exist, but if it does exist it should append it to the end of the values for that particular key. ie like the normal push action with arrays.
Expected behaviour:
key = 'hello'
value = 'thanks'
obj = {'hello' : ['thanks']}
key = 'goodbye'
value = 'ok'
obj = {'hello' : ['thanks'], 'goodbye' : ['ok']}
key = 'hello'
value = 'why'
obj = {'hello' : ['thanks','why'], 'goodbye' : ['ok']}
The value 'why' is appended to the end for key 'hello'.
EDIT: All values are put into arrays.
6 Answers 6
You could create custom function for this that checks if the key exists in object and based on that sets value directly or turns it into an array.
let obj = {
foo: 'bar'
};
let add = (obj, key, val) => {
if (key in obj) obj[key] = [].concat(obj[key], val);
else obj[key] = val;
}
add(obj, 'foo', 'baz');
add(obj, 'bar', 'baz');
console.log(obj)
You could also use Proxy with set trap that will run when you try to set new property on proxy object.
const obj = {
foo: 'bar'
}
const proxy = new Proxy(obj, {
set(obj, prop, value) {
if (prop in obj) obj[prop] = [].concat(obj[prop], value)
else obj[prop] = value;
}
})
proxy.foo = 'bar';
proxy.bar = 'baz';
console.log(proxy)
Comments
Fairly simple - use the logical OR operator ||:
let obj = {};
const key = "key";
const value = "value";
obj[key] = obj[key] || [];
obj[key].push(value);
obj[key].push("anotherValue");
console.log(obj);
.as-console-wrapper { max-height: 100% !important; top: auto; }
9 Comments
{key: "value"} instead of an empty object?{ "key": [ "value" ] } which is not what OP wants. Only if the property is assigned again, it should create an arrayYou can also do this via Object.assign in a pretty concise way:
let o = {}
let add = (obj, k, v) => Object.assign(obj, obj[k]
? { [k]: [].concat(obj[k], v) }
: { [k]: v })
console.log(add(o, 'a', 1))
console.log(add(o, 'b', 2))
console.log(add(o, 'a', 3))
console.log(add(o, 'a', 4))
The idea is to use the ternary operator and check if we already have the key and if so concat it to a new array. otherwise just assign a new object.
Comments
You can create a prototype function for your requirement
Object.prototype.add = function(key, value) {
if( this[key] != undefined) this[key] = [].concat(this[key], value);
else this[key] = value;
};
let obj = {'hello' : 'thanks', 'goodbye' : 'ok'}
let key = 'hello'
let value = 'why'
//obj[key] = value;
obj.add(key,value);
console.log(obj)
1 Comment
add functionality and then do Object.create(adder) to derive your new ones.Try (I take this comment into account)
let obj = {};
const key = 'some_key';//a string
const value = 'first value' ;//a string
obj[key]= (obj[key]||[]).concat(value);
obj[key]= (obj[key]||[]).concat('next value');
console.log(obj);
Comments
Try this. However, this will also put the first value in an array, but that's quite a standard behaviour if you know it's going to be an array of values.
if(obj[key]){
obj[key].push(value);
}
else{
obj[key] = [value];
}
2 Comments
value, not [value]
obj = {'hello' : 'thanks'}and notobj = {'hello' : ['thanks']}if you know in advance thathellois going to hold more than one value?obj.add('key', [1, 2])andobj.add('key', 1); obj.add('key', 2)produces the same object, but they must be treated differently when you try to add one more time.