I have an array of generated objects like the following:
[
{obj1: {
key: 'value'
}},
{obj2: {
key: 'value2'
}},
{obj3: {
key: 'value3'
}}
]
I would like to flatten the array, with the following output:
[
{
key: 'value'
},
{
key: 'value2'
},
{
key: 'value3'
}
]
I am doing this with a for loop, which works, but the array will be quite large in size and wonder if there is a more efficient way to do this?
for (var key in array) {
let obj = array[key];
for (var key in obj) {
newArray.push(obj[key]);
}
}
output:
newArray: [
{
key: 'value'
},
{
key: 'value2'
},
{
key: 'value3'
}
]
I'm looking for the simplest method, ES6 or Lodash also welcome for solutions.
Updated to reflect correct array format.
You can simply use reduce and Object.values
let arr = [{obj1: {key: `value`}},{obj2: {key: `value2`
}},{obj3: {key: `value3`}}]
let op = arr.reduce((op,e)=> op.concat(Object.values(e)),[])
console.log(op)
You can use simple for loop when you care about speed.
let arr = [{obj1: {key: `value`}},{obj2: {key: `value2`
}},{obj3: {key: `value3`}}]
let op = []
for(let i=0; i<arr.length; i++){
let values = Object.values(arr[i])
op = op.concat(values)
}
console.log(op)
You can use Array.map, and Object.values.
Map "maps" each element in an array to a new array.
It takes each element of an array, and performs an operation on it.
The result of this operation becomes the corresponding element in a new Array.
This new Array is what's returned.
To convert Objects into Arrays: you can use Object.values, Object.keys, and Object.entries.
Object.values de-references each key in an object, and turns it into an array element holding that key's value.
const arr = [
{obj1: {key: 'value'}},
{obj2: {key: 'value2'}},
{obj3: {key: 'value3'}}
];
let newArr = arr.map(obj => (
{key: Object.values(obj)[0].key}
));
console.log(newArr);
To return an object, it must be wrapped in parenthesis.
In the first iteration, obj == { obj1: { key: 'value' }}, the first element in the input Array, arr.
And,
Object.values(obj) == [{key: 'value'}]
So, we need to grab the element at index 0 to pull the object out of the array {key: 'value'}.
Alternatively, if you know you can rely on the naming structure of the elements in your array (the outer object's key), you could do this, which may be easier to reason about:
const arr = [
{obj1: {key: 'value'}},
{obj2: {key: 'value2'}},
{obj3: {key: 'value3'}}
];
let newArr2 = arr.map( (obj, i) => (
{ key: obj['obj'+(i+1)].key }
));
console.log(newArr2);
Note: you'll need to wrap the i+1 in parenthesis, to force addition to take precedence over JS auto type conversion and string concatenation. Otherwise instead of obj1, obj2, obj3, you'll get obj01, obj11, obj21 as the object keys.
Related
Let's take 2 objects and let's say I want to dynamically add a key to the first object with the value of the second, and to do this I want to use the spread operator.
let object1 = { key: 'myKey1', value:1 };
let object2 = { field: 'key', displaValue:'chiave' };
something like this:
let object3 = {...object1, [object2.displayValue)]: object1[object2.field] }
But unfortunately I have this result with the undefined key:
{key: "myKey1", value: 1, undefined: "myKey1"}
Expected result:
{key: "myKey1", value: 1, chiave: "myKey1"}
Please read carefully the question, this is not a duplicate of:
ECMAScript 6 arrow function that returns an object
javascript cannot map array of objects with nested values
map function for objects (instead of arrays)
Loop through an array in JavaScript
map function for objects (instead of arrays)
Loop through an array in JavaScript
Let's consider the following array of object:
var obj = [{ 'key1' : 'value1' }, { 'key2' : 'value2' }];
I would like to map the array to get keys and values for each object. Something like:
obj.map((key, val) => console.log(key, val));
I already try many stuff like Object.entries(obj) but it always results in complicated solution with many brackets like Object.entries(obj)[0][1]
Is there a simple, nice and efficient way to map an array of object? Note I need key and value for each object
You seem like you only want to print it out or access them:
.map changes an array to a different array, which doesn't seem like what you are looking for.
var objs = [{ 'key1' : 'value1' }, { 'key2' : 'value2' }];
objs.forEach(obj => {
for (let p in obj) console.log(p, obj[p]);
});
If you are looking for key1=value1&key2=value2 as the answer and you know you only have 1 key and value in each object, then it is:
let objs = [{ 'key1' : 'value1' }, { 'key2' : 'value2' }];
let s = objs.map(obj => `${Object.keys(obj)[0]}=${Object.values(obj)[0]}`).join("&");
console.log(s);
But you probably want to use encodeURIComponent() to encode the params, making it:
let objs = [{ 'key1' : 'value1 hello' }, { 'key2' : 'value2 & 3' }];
let s = objs.map(obj => `${encodeURIComponent(Object.keys(obj)[0])}=${(encodeURIComponent(Object.values(obj)[0]))}`).join("&");
console.log(s);
If your keys are all alphanumeric and underscore characters, then you shouldn't need to use encodeURIComponent() on the key.
var obj = [{ 'key1' : 'value1' }, { 'key2' : 'value2' }];
obj.forEach(el => {
for (var prop in el) {
console.log(prop, el[prop])
}
})
// results:
// key1 value1
// key2 value2
Not as clean as what #nopole answer, but this kind achieve what you want for a key, value object.
var objs = [{ 'key1' : 'value1' }, { 'key2' : 'value2' }];
objs.forEach(obj => {
// loop over keys-and-values
for (let [key, value] of Object.entries(obj)) {
console.log(key, value);
}
});
Also this works for object with more than one key:
var objs = [{ 'key1' : 'value1', "key2":"value2" }, { 'key3' : 'value3' }];
objs.forEach(obj => {
// loop over keys-and-values
for (let [key, value] of Object.entries(obj)) {
console.log(key, value);
}
});
Consider having the following json
[
{'key1': { ... }},
{'key2': { ... }},
{'key3': { ... }}
]
I want to extract the keys for those objects in an elegant way, the following code is working, but it seems ugly to me.
let result = objects.map(o => Object.keys(o))[0]
the [0] at the end because the returned value is an array of array
You can use .concat() and .map() methods to get the desired result:
let data = [
{'key1': { }},
{'key2': { }},
{'key3': { }}
];
let result = [].concat(...data.map(Object.keys));
console.log(result);
References:
Array.prototype.concat()
Array.prototype.map()
Object.keys()
Spread Syntax
An array can only hold values, objects hold key/value pairs. Don't forget to use JSON.parse(json) before actually manipulating the data.
I'm guessing you need something along the lines of:
const list = [
{1: "one"},
{2: "two"},
{3: "three"}
];
I edited your JSON.
const data = [
{ 'key2': { }} ,
{'key1': { }},
{'key3': { }}
];
const result = [].concat.apply([], data.map(Object.keys));
console.log(result);
Is this possible in lodash or any other javascript/typescript way
var obj = {
a: [ {id:1},{id:2},{id:3}]
b: [ {id:4},{id:5},{id:6}]
c: [ {id:7},{id:8},{id:9}]
}
// transform to
var arr = [
{title:a, items:[{id:1},{id:2},{id:3}]},
{title:b, items: [ {id:4},{id:5},{id:6}]},
{title:c, items: [ id:7},{id:8},{id:9}]}
]
You can use Object.keys for that:
var obj = {
a: [ {id:1},{id:2},{id:3}],
b: [ {id:4},{id:5},{id:6}],
c: [ {id:7},{id:8},{id:9}]
}
var result = Object.keys(obj).map(function(key) {
return { title: key, items: obj[key] }
})
console.log(result);
You can use a highly-readable one-liner for this with lodash and ES6:
_.map(obj, (items, title) => ({ title, items }));
You can completely avoid Object.keys() because map() works on objects. The callback function gets the object key and the value of that key as arguments. So, you can name them in such a way that allows for object literal shorthand notation, as we've done here with items and title.
The result set is [{key: key1, value: value1}, {key: key2, value: value2}], what method should I use in Javascript to get the value of a particular key. Example I need the value for 'key2'. Is there a specific method or should I use a loop?
Thanks in advance.
I would convert that result set to an index object, and then perform all subsequent look-ups on the index object. That way you only have to iterate over the result set once.
Below is a straightforward implementation based on the reduce method.
var results = [{key: "key1", value: "value1"}, {key: "key2", value: "value2"}];
var index = results.reduce(function(index, result) {
index[result.key] = result.value;
return index;
}, {});
alert(index.key2);
As mentioned in the comments, if you don't need to do multiple look-ups, but just need to extract one value, using a regular for-loop will be faster and use less memory.
var results = [{key: "key1", value: "value1"}, {key: "key2", value: "value2"}];
for (var i=0; i < results.length; i++) {
if (results[i].key === 'key2') {
alert(results[i].value);
break;
}
}