How to copy an array of strings into an object - javascript

I have an array of strings and an object:
const arr = ['abc', 'def'];
const obj = {
foo: true,
bar: 42,
};
I need to add the values in arr as keys in obj, so that the resulting object will look like:
const result = {
foo: true,
bar: 42,
abc: true,
def: true,
};
This is what I tried:
{ ...obj, ...arr.map(x => ({[x]: true })) }

you can simply use Object.assign() :
The below given example will mutate the original object :
let arr = ['abc', 'def'];
let obj = {
foo: true,
bar: 42,
};
// Note it will mutate the original object
arr.forEach((e)=> Object.assign(obj, {[e] :true }));
console.log(obj);
In case you don`t want to mutate the original object try the following:
let arr = ['abc', 'def'];
let obj = {
foo: true,
bar: 42,
};
let result = Object.assign({}, obj);
arr.forEach((e)=> Object.assign(result, {[e] :true }));
console.log(result);

Another way would be using reduce method
This will mutate the obj and result will point to the obj. Meaning that changing one of them changes both.
const result = arr.reduce((acc, item) => {
acc[item] = true;
return acc;
}, obj);
If you do not wish to mutate the obj then use the spread operator
const result = arr.reduce((acc, item) => {
acc[item] = true;
return acc;
}, { ...obj });

const arr = ['abc', 'def'];
const obj = {
foo: true,
bar: 42,
};
const result = {...obj}; // don't modify the original obj
arr.forEach(i => result[i] = true);

You could take a copy of the object and map the wanted properties.
var array = ['abc', 'def'],
object = { foo: true, bar: 42 },
result = Object.assign({}, object, ...array.map(k => ({ [k]: true })));
console.log(result);

How about:
Object.assign({}, obj, ...arr.map(x => ({[x]: true})))
Demo:
const arr = ['abc', 'def'];
const obj = {foo: true, bar: 42};
const result = Object.assign(obj, ...arr.map(x => ({[x]: true})));
console.log(result);

Related

ES6 spread syntax : skip empty keys automatically?

What is simpler pattern to avoid updating inputs if one of the keys is empty in payload ?
Is there a nice ES6 syntax ?
const master = {
inputs: {a: [], b: [], c: []}
};
const {a, b, c} = payload;
const updateMaster = (payload) => ({
...master, inputs: {...master.inputs, ...payload}
});
To filter the fields of an object, use Object.entries to retrieve the fields, Array.prototype.filter to filter then, and Object.formEntries to reconstruct an object from the filtered entries.
let payload = {
a: [],
b: [1, 2]
};
let nonEmptyPayload = Object.fromEntries(Object.entries(payload).filter(([_, v]) => v.length))
console.log(nonEmptyPayload);
Applying this to your example,
let master = {
inputs: {
a: [],
b: [13, 14],
c: [10, 12]
}
};
let trimObj = obj => Object.fromEntries(Object.entries(obj).filter(([_, v]) => v.length));
let updateMaster = payload => ({
...master,
inputs: { ...master.inputs,
...trimObj(payload)
}
});
updateMaster({
b: [15, 16], // Will override master.c
c: [] // Will not override master.c
});
console.log(master);
You could create a function like this. It removes all empty values from an object, without directly modifying the object passed to the function.
const removeEmpty = obj => {
return Object.keys(obj).reduce((acc, key) => {
// value is "falsey" or is empty array
return !obj[key] || (Array.isArray(obj[key]) && !obj[key].length)
? acc
: {...acc, [key]: obj[key]}
}, {})
}
console.log(removeEmpty({a: 'AAA', b: '', c: 'CCC', d: false, e: null, f: [1,2], g: []}))
So your final snippet would look like this:
const updateMaster = (payload) => ({
...master, inputs: {...master.inputs, ...removeEmpty(payload)}
});

How to read each object inside object and move to array

I have a requirement to move each object of object into array.
My object looks like below
obj = { obj1: {}, obj2: {}, obj3: {}}
I need to convert each object into array and it should look like below
array[0] = obj1
array[1] = obj2
array[2] = obj3
Can someone please help me?
3 different methods
const obj = { obj: { name: 'obj1' }, obj2: { name: 'obj2' }, obj3: { name: 'obj3' }}
// option 1
const arr = []
for (let key in obj)
arr.push(obj[key])
// option 2
const arr2 = Object.keys(obj).map(key => obj[key])
// option 3
const arr3 = Object.values(obj)
console.log(arr)
console.log(arr2)
console.log(arr3)
Use Object.values:
const obj = {obj1: {foo: 'bar'}, obj2: {foo: 'baz'}}
const result = Object.values(obj)
console.log(result)
From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values
The Object.values() method returns an array of a given object's own enumerable property values, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).
const input = { obj1: {}, obj2: {}, obj3: {}};
console.log(Object.values(input));
(3) [{…}, {…}, {…}]
0: {}
1: {}
2: {}
length: 3
Simple as this
let obj = { obj1: {}, obj2: {}, obj3: {}}
console.log(Object.keys(obj).map(k => obj[k]))
const obj = {obj1: {foo: 'bar',foo1: 'bar1'}, obj2: {foo: 'baz'}}
var keyObj = Object.keys(obj);
var valueObj = Object.values(obj);
const newObj = [];
for(let i = 0;i < keyObj.length;i++) {
var tmp = [];
tmp[keyObj[i]] = valueObj[i];
newObj.push(tmp);
}
console.log(newObj);

filter the properties of an object based on an array. And get the filtered object

how can i filter the properties of an object based on an array. I have sample snippet below.
var obj = {a: [], b:[], c: [], d:[]}
var arr = ["a", "b"]
Following is my expected output, how can i achieve this
var outupt = {a: [], b:[]}
You could map new objects and create a single object.
var object = { a: [], b: [], c: [], d: [] },
keys = ["a", "b"],
result = Object.assign(...keys.map(k => ({ [k]: object[k] })));
console.log(result);
var obj = {a: [], b:[], c: [], d:[]}
var arr = ["a", "b"]
var output = arr.reduce((result, key) => ({ ...result, [key]: obj[key] }), {});
console.log(output)

Create object from forEach

I'm trying to figure out if there's a way to rewrite this code as a single object creation:
my_array = [
{key: 1, value: "foo"},
{key: 2, value: "bar"}
];
let my_obj = {};
my_array.forEach((elem) => {
my_obj[elem.key] = elem.value;
});
What I'd like to do is something like:
my_array = [
{key: 1, value: "foo"},
{key: 2, value: "bar"},
];
const my_obj = ...?
Is there a way to do a one-shot conversion that's equivalent to the forEach call?
You can achieve this using Array.prototype.reduce():
var my_array = [{key: 1, value:"foo"}, {key: 2, value:"bar"}];
var my_object = my_array.reduce(function(prev, curr) {
prev[curr.key] = curr.value;
return prev;
}, {});
console.log(my_object); // {"1": "foo", "2": "bar"}
Alternatively, using ES6 syntax:
const my_object = my_array.reduce((prev, curr) => {
prev[curr.key] = curr.value;
return prev;
}, {});
In ES6, you can use Object.assign:
const obj = Object.assign({}, ...my_array.map(x => ({ [x.key]: x.value })));
// Or:
const obj = Object.assign({}, ...my_array.map(({ key, value }) => ({ [key]: value })));
This converts each { key: foo, value: bar } to { foo: bar }, then uses Object.assign to merge them into one object. (The spread operator is used as Object.assign expects a variable list of arguments.)
You can use the reduce function. It should work like this:
my_array = [
{key: 1, value: "foo"},
{key: 2, value: "bar"}
];
let my_obj = my_array.reduce(function(obj, elem) {
obj[elem.key] = elem.value;
return obj;
}, {});
// my_obj = { "1": "foo", "2": "bar" }

Array of objects to object of property values

I have this data:
[
{foo: 1, bar: a},
{foo: 2, bar: b},
{foo: 3, bar: c},
]
What's the simplest way to transform the data to something like
{
customLabel1 : [1,2,3],
customLabel2 : [a,b,c]
}
I come up with this
{
customLabel1: data.map((a) => {return a.foo} ),
customLabel2: data.map((a) => {return a.bar} )
}
Is there a simpler way to do this, or faster?
If you want simpler, your code is already pretty close with fat arrow syntax. You can drop the parentheses and the return keyword:
{
customLabel1: data.map(a => a.foo),
customLabel2: data.map(a => a.bar)
}
If you want faster, I think you'll have to sacrifice some simplicity. As it's written, you're looping over data twice. If you iterated once, it would look something like this:
var data = [
{foo: 1, bar: 'a'},
{foo: 2, bar: 'b'},
{foo: 3, bar: 'c'},
];
var o = {customLabel1: [], customLabel2: []};
data.forEach(a => {
o.customLabel1.push(a.foo);
o.customLabel2.push(a.bar);
});
console.log(o);
You can use this form if you dont know the keys
{
customLabel1: data.map(function(element) { return element[Object.keys(element)[0]];}),
customLabel2: data.map(function(element) { return element[Object.keys(element)[1]];})
}
You could use an object for the key mapping and iterate then.
var data = [{ foo: 1, bar: 'a' }, { foo: 2, bar: 'b' }, { foo: 3, bar: 'c' }],
labels = { customLabel1: 'foo', customLabel2: 'bar' },
result = {};
data.forEach(a => Object.keys(labels).forEach(k => {
result[k] = result[k] || [];
result[k].push(a[labels[k]]);
}));
console.log(result);
The shorter syntax of the map call can be:
data.map(el => el.prop);
Having said that, I'd define a helper function for this:
function pluck(arr, props) {
return Object.keys(props).reduce((ret, prop) => {
ret[prop] = arr.map(el => el[props[prop]]);
return ret;
}, {});
}
var ret = pluck(data, {
customLabel1: 'foo',
customLabel2: 'bar'
});

Categories

Resources