Create object from forEach - javascript

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" }

Related

extracting object from array of array using es6

how can i return an array of objects taking from array of again one more level array. I am using push.
is there any better way to achieve this
let a = [{b: [{c: "k"}]}]
let o = []
a.forEach(so => {so.b.forEach(obc => o.push(obc))})
console.log(o)
I'd use flatMap() instead:
const a = [{
b: [{
foo: 'foo'
}]
},
{
b: [{
c: "k"
},
{
bar: 'bar'
}
]
}
];
const o = a.flatMap(({ b }) => b);
console.log(o);
(but this is a relatively new method, so if you want to use it and still support older environments, be sure to include a polyfill)
Lacking that, you can also improve your existing code by using concat() with the inner array instead of iterating over each inner item:
const a = [{
b: [{
foo: 'foo'
}]
},
{
b: [{
c: "k"
},
{
bar: 'bar'
}
]
}
];
let o = [];
a.forEach(({ b }) => {
o = o.concat(b);
});
console.log(o);
Try
let a = [{b: [{c: "k"}]}]
let o =a[0].b
console.log(o)

How to Map Array values from one Array to Another Array JavaScript?

This is my Code. Where I want to Pass the Values of kvArray to Second Array.
var kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
var reformattedArray = kvArray.map(obj => {
var payload = {};
payload["rt"];
payload["do"];
payload["f1"];
payload[obj.key] = obj.value;
console.log(payload["rt"]);
return payload;
});
The console.log is coming undefined.
Can anyone help here? I am pretty new to Map function.
I want to Print this result.
payload["do"]=10
payload["f1"]=20
payload["f2"]=30
var kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
var reformattedArray = kvArray.map(obj =>{
var payload = {};
const mapping = [null, 'rt', 'do', 'f1'];
const key = mapping[obj.key];
payload[key] = obj.value;
return payload;
});
console.log(reformattedArray);
You could use a destructuring assignment and build a new object with computed property names.
For the final keys, you could use an object keys with corresopnding keys to the the keys of the given object.
var kvArray = [{ key: 1, value: 10 }, { key: 2, value: 20 }, { key: 3, value: 30 }],
keys = { 1: 'rt', 2: 'do', 3: 'fi' },
result = kvArray.map(({ key, value }) => ({ [keys[key]]: value }));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I'm not sure what format you want.
try the code below:
var kvArray = [{ key: 1, value: 10 },
{ key: 2, value: 20 },
{ key: 3, value: 30 }];
var reformattedArray = kvArray.map(obj => obj.value);
console.log(reformattedArray)
the result will be:
[ 10, 20, 30 ]
Not sure what you are trying to achieve with lines:
payload["rt"];
payload["do"];
payload["f1"];
If you want to create new keys in the reformatterArray, try assigning a value, eg.
var kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
var reformattedArray = kvArray.map(obj =>{
var payload = {};
payload["rt"] = "";
payload["do"]= "";
payload["f1"]= "";
payload[obj.key] = obj.value;
console.log(payload["rt"]);
return payload;
});
console.log(reformattedArray):
//result
0: {1: 10, rt: "", do: "", f1: ""}
1: {2: 20, rt: "", do: "", f1: ""}
2: {3: 30, rt: "", do: "", f1: ""}
You were assigning the value to payload but getting the values of payload.
var kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
var reformattedArray = kvArray.map(obj =>{
var payload = {};
payload[obj.key] = obj.value;
console.log(payload[obj.key]);
return payload;
});
You are mapping data to reformattedArray , so you need to pring reformattedArray to get values,
var kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
var reformattedArray = kvArray.map(obj =>{
var payload = {};
payload[obj.key] = obj.value;
return payload;
});
console.log(reformattedArray);
Also you have following code which is of no use
payload["rt"];
payload["do"];
payload["f1"];
This code works fine
let kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
let reformattedArray = kvArray.map(obj =>{
var payload = {};
payload[obj.key] = obj.value;
return payload;
});
console.log(reformattedArray)
The above code print output like this
[
0: {1: 10}
1: {2: 20}
2: {3: 30}
]
For more info, refer this link

How to copy an array of strings into an object

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);

Intersection of values of 2 arrays of objects

I have 2 arrays in the form:
array1 = [{key1: value1}, {key1: value2}, ...];
array2 = [{key2: value0}, {key2: value2}, ...];
where the object keys in both arrays are different, but the values may match. I would like to write some code that gets the intersection between the two arrays where in the above example, it should return: [value2].
I tried using:
array1.filter(function(n)) {
return array2.indexOf(n) != -1;
});
but of course I got an empty array because the keys mismatch. Can the above code be modified to ignore the object keys and match only their values?
var kiran = [];
var array1 = [{ key1: 'value1' }, { key1: 'value2' }];
var array2 = [{ key2: 'value0' }, { key2: 'value2' }];
array1.map(function(item1){
array2.map(function(item2){
if(item1.key1 === item2.key2){
kiran.push(item2.key2);
}
})
})
console.log(kiran);
How about below approach
const array1 = [{ key1: 'value1' }, { key1: 'value2' }];
const array2 = [{ key2: 'value0' }, { key2: 'value2' }];
const result = array1.filter(c => array2.findIndex(x=>x.key2 == c.key1) > -1)
console.log(result);
You could use a hash table and with a binary value. Then check if the count is equal to three, then take that key as result.
var array1 = [{ key1: 'value1' }, { key1: 'value2' }],
array2 = [{ key2: 'value0' }, { key2: 'value2' }],
hash = Object.create(null),
incHash = function (i) {
return function (o) {
Object.keys(o).forEach(function (k) {
hash[o[k]] = (hash[o[k]] || 0) | 1 << i;
});
};
},
result;
[array1, array2].forEach(function (a, i) {
a.forEach(incHash(i));
});
result = Object.keys(hash).filter(function (k) {
return hash[k] === 3;
});
console.log(result);
console.log(hash);
If you can use third party library then I suggest Lodash. An incredibly usefull utility library.
You can use _.intersectionWith() funciton to get your task done in one line
var array1 = [{ key1: 'value1' }, { key1: 'value2' }],
array2 = [{ key2: 'value0' }, { key2: 'value2' }];
var intersection = _.map(_.intersectionWith(array1, array2, function(item1,item2){
return item1.key1 === item2.key2;
}),'key1');
console.log(intersection);
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js">
</script>

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