I want to set multiple objects as multiple values of another object. So for example
let dataObj ={}
const personData = {name:"sai",age:"20"}
const ids = {id1:"1231455",id2:"425325232"}
dataObj.personData = personData;
dataObj.ids = ids
console.log(dataObj);
'personData' is a object and 'ids' is a object.Im setting these 2 objects as 2 values for 'dataObj'.
I was wondering is there a shorter way to achieve this like:
let dataObj ={}
const personData = {name:"sai",age:"20"}
const ids = {id1:"1231455",id2:"425325232"}
dataObj = personData;
dataObj = ids
console.log(dataObj);
The problem with the alternative I suggested is that it wont set 'key' of 'dataObj' object.It will just set the values of 'personData' and 'ids' to the value of dataObj.Is there any way I can achieve this ? Specifying multiple objects as values to another object with keys?
You can achieve this using the spread syntax:
let dataObj = {};
const personData = {name:"sai",age:"20"}
const ids = {id1:"1231455",id2:"425325232"}
dataObj = { ...dataObj, personData, ids };
console.log(dataObj);
/*
output :
value of dataObj:
{
personData: {
name: "sai",
age" "20"
},
ids: {
id1: "1231455",
id2: "425325232"
}
}
*/
I'll try and explain spread using the above example. First we start with an empty object dataObj: {}. We want to add new properties to that object: personData with the personData object as value and ids with the ids object as value.
ES2015 added a shorthand syntax for setting property definitions in objects. That's what been used here:
dataObj = { personData, ids };
This is simply a cleaner way of writing
dataObj = {
personData: personData,
ids: ids
};
More info on this can be found on MDN.
Because you want to initialise your object before, we can't simply overwrite the object, but we need to add the new properties to the existing object. This can be done using the spread syntax.
const oldObject = { key: 'value', anotherKey: 'another value' };
let newObject = { ...oldObject };
// newObject value: { key: 'value', anotherKey: 'another value' };
The oldObject was 'spreaded' in newObject. Resulting it in having the same key-value pairs as oldObject.
In your code example we assign a new object to dataObj. In that new object we spread all properties which are in the current dataObj: { ...dataObj and then add the new properties: , personData, ids }.
I hope this explanation is clear, feel free to ask for more info. The spread syntax is very powerful and can be used for a lot of things. So be sure to read up on that.
You can merge two objects as below. You can use '...' spread object. the spread object works for objects as well. Clone an object as shown in below code. for more information please visit https://flaviocopes.com/javascript-spread-operator/
let dataObj = {}
const personData = { name: "sai", age: "20" }
const ids = { id1: "1231455", id2: "425325232" }
dataObj = { ...dataObj, personData, ids }
console.log(dataObj);
Related
Suppose there is an array like this:
const a = [ {p:1}, {p:2}, {p:3} ];
Is it possible to destructure this array in order to obtain p = [1, 2, 3] ?
Because this does not work :
const [ ...{ p } ] = a; // no error, same as const p = a.p;
// p = undefined;
Edit
In response to all the answers saying that I need to use Array.prototype.map, I am aware of this. I was simply wondering if there was a way to map during the destructuring process, and the answer is : no, I need to destructure the array itself, then use map as a separate step.
For example:
const data = {
id: 123,
name: 'John',
attributes: [{ id:300, label:'attrA' }, { id:301, label:'attrB' }]
};
function format(data) {
const { id, name, attributes } = data;
const attr = attributes.map(({ label }) => label);
return { id, name, attr };
}
console.log( format(data) };
// { id:123, name:'John', attr:['attrA', 'attrB'] }
I was simply wondering if there was a way, directly during destructuring, without using map (and, respectfully, without the bloated lodash library), to retrive all label properties into an array of strings.
Honestly I think that what you are looking for doesn't exist, normally you would map the array to create a new array using values from properties. In this specific case it would be like this
const p = a.map(element => element.p)
Of course, there are some packages that have many utilities to help, like Lodash's map function with the 'property' iteratee
you can destructure the first item like this :
const [{ p }] = a;
but for getting all values you need to use .map
and the simplest way might be this :
const val = a.map(({p}) => p)
Here's a generalized solution that groups all properties into arrays, letting you destructure any property:
const group = (array) => array.reduce((acc,obj) => {
for(let [key,val] of Object.entries(obj)){
acc[key] ||= [];
acc[key].push(val)
}
return acc
}, {})
const ar = [ {p:1}, {p:2}, {p:3} ];
const {p} = group(ar)
console.log(p)
const ar2 = [{a:2,b:1},{a:5,b:4}, {c:1}]
const {a,b,c} = group(ar2)
console.log(a,b,c)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
{"1":"val1","2":"val2","3":"val3"}
i want it to converted like this:
{"Id":"1","value":"val1","Id":"2","value":"val2","Id":"3","value":"val3"}
little Help Please would be much appricated
You can't use the same key name in one object.
instead you can do this.
const origin = {"1":"val1","2":"val2","3":"val3"}
const converted = Object.entries(origin).map( ([key,value]) => ({id: key, value }) );
console.log(converted);
What you have posted is invalid.
What you might want is:
const object = {"1":"val1","2":"val2","3":"val3"};
console.log(Object.entries(object));
// or
console.log(Object.keys(object).map(i => ({Id: i, value: object[i]})));
You could use a loop over Object.entries.
E.g. something like:
const newObjArr = [];
for(let [key, value] of Object.entries(obj)){
newObj.push({Id: key, value});
}
The above would return an array of objects, but I'm sure you can amend it to your particular use case.
const data = {"1":"val1","2":"val2","3":"val3"};
const result = Object.keys(data).map((key) => ({ id: key, value: data[key] }));
The result will be [{ id: "1", value: "val1" }, { id: "2", value: "val2" }, { id: "3", value: "val3" }]
As pointed out this is invalis. If you want to convert it if would look like this:
[{"Id":"1","value":"val1"},{"Id":"2","value":"val2"},{"Id":"3","value":"val3"}]
You can make an function that converts this.
const object = {"1":"val1","2":"val2","3":"val3"};
console.log(Convert(object));
function Convert(obj){
return Object.keys(obj).map(i => ({Id: i, value: obj[i]}));
}
You cannot do this. Object is a unique key value pair.
{"Id":"1","value":"val1","Id":"2","value":"val2","Id":"3","value":"val3"}
Suppose you want to merge two object and What if both the object has same key, it simply merge the last objects value and have only one key value.
You can convert your large object to several small objects and store them in an array as this snippet shows. (It could be much shorter, but this verbose demo should be easier to understand.)
// Defines a single object with several properties
const originalObject = { "1" : "val1", "2" : "val2", "3" : "val3" }
// Defines an empty array where we can add small objects
const destinationArray = [];
// Object.entries gives us an array of "entries", which are length-2 arrays
const entries = Object.entries(originalObject);
// `for...of` loops through an array
for(let currentEntry of entries){
// Each "entry" is an array with two elements
const theKey = currentEntry[0]; // First element is the key
const theValue = currentEntry[1]; // Second element is the value
// Uses the two elements as values in a new object
const smallObject = { id: theKey, value: theValue };
// Adds the new object to our array
destinationArray.push(smallObject);
} // End of for loop (reiterates if there are more entries)
// Prints completed array of small objects to the browser console
console.log(destinationArray);
const obj = {"1":"val1","2":"val2","3":"val3"}
const newObject = Object.keys(obj).map(e => {
return {ID: e , value : obj[e] }
});
console.log(newObject); // [ { ID: '1', value: 'val1' },
{ ID: '2', value: 'val2' },
{ ID: '3', value: 'val3' } ]
it will give u an array of object, later u need to convert it to object and flat the object:
How do I convert array of Objects into one Object in JavaScript?
how to convert this nested object into a flat object?
Using Javascript, how do I create an array within an object that's within an object, so that my value is stored at: main[1].type[1][0]
I have tried and my code which does not work is as follows:
let main = []
main[1] = {type: {1:['Value1', 'Value2']}, {2:['Value3', 'Value4']}};
console.log(main[1].type[0][1]);
I expect main[1].type[1][0] to be 'Value1' but it is undefined
You're not getting undefined. You have a syntax error. A comma should either be separating array values, or separating object entries. You have a comma here, in an object, so it is expected to have a key after it, not a {
main[1] = {type: {1:['Value1', 'Value2']}, {2:['Value3', 'Value4']}};
|
|
Remove the } and { around this comma
Remove the } and { around the comma so that {1:['Value1', 'Value2'], 2:['Value3', 'Value4']} becomes a single object with two keys:
const main = [];
main[1] = {type: {1:['Value1', 'Value2'], 2:['Value3', 'Value4']}};
console.log( main[1].type[1][0] );
First your declaration is wrong and will not works.
{type: {}, {}} isn't a valid JSON and you must wrap it into [] to create array of object {type: [{}, {}]}.
Also by adding a level you will have to ask for: main[1].type[0][1][0] to get the complet path to Value1
let main = []
main[1] = {type: [{1:['Value1', 'Value2']}, {2:['Value3', 'Value4']}]};
console.log(main[1].type[0][1][0])
Your problem is you can not create an object with a numbered object inside it you have to use the array notation var variableName = [/*variable values here separated by commas*/]
This will fix your problem:
let main = []
main[1] = {
type: [
['Value1', 'Value2'],
['Value3', 'Value4']
]
};
console.log(main[1].type[0][1]);
Breaking down your issue, an object must be "zero or more pairs of property names and associated values of an object." The second value in the question's code does not have a key, causing an uncaught SyntaxError.
Here's an object literal that returns your desired result:
const main = {
1: {
type: { 1: ['Value1', 'Value2'] },
otherType: { 2: ['Value3', 'Value4'] },
},
};
main[1].type[1][0]
=> "Value1"
Object initializer docs
Another option could be to use sparse arrays :
let main = [, { type: [, ['Value1', 'Value2'], ['Value3', 'Value4'] ] } ];
console.log(main[1].type[1][0]);
Okay, so I am trying to create a function that allows you to input an array of Objects and it will return an array that removed any duplicate objects that reference the same object in memory. There can be objects with the same properties, but they must be different in-memory objects. I know that objects are stored by reference in JS and this is what I have so far:
const unique = array => {
let set = new Set();
return array.map((v, index) => {
if(set.has(v.id)) {
return false
} else {
set.add(v.id);
return index;
}
}).filter(e=>e).map(e=>array[e]);
}
Any advice is appreciated, I am trying to make this with a very efficient Big-O. Cheers!
EDIT: So many awesome responses. Right now when I run the script with arbitrary object properties (similar to the answers) and I get an empty array. I am still trying to wrap my head around filtering everything out but on for objects that are referenced in memory. I am not positive how JS handles objects with the same exact key/values. Thanks again!
Simple Set will do the trick
let a = {'a':1}
let b = {'a': 1,'b': 2, }
let c = {'a':1}
let arr = [a,b,c,a,a,b,b,c];
function filterSameMemoryObject(input){
return new Set([...input])
}
console.log(...filterSameMemoryObject(arr))
I don't think you need so much of code as you're just comparing memory references you can use === --> equality and sameness .
let a = {'a':1}
console.log(a === a ) // return true for same reference
console.log( {} === {}) // return false for not same reference
I don't see a good reason to do this map-filter-map combination. You can use only filter right away:
const unique = array => {
const set = new Set();
return array.filter(v => {
if (set.has(v.id)) {
return false
} else {
set.add(v.id);
return true;
}
});
};
Also if your array contains the objects that you want to compare by reference, not by their .id, you don't even need to the filtering yourself. You could just write:
const unique = array => Array.from(new Set(array));
The idea of using a Set is nice, but a Map will work even better as then you can do it all in the constructor callback:
const unique = array => [...new Map(array.map(v => [v.id, v])).values()]
// Demo:
var data = [
{ id: 1, name: "obj1" },
{ id: 3, name: "obj3" },
{ id: 1, name: "obj1" }, // dupe
{ id: 2, name: "obj2" },
{ id: 3, name: "obj3" }, // another dupe
];
console.log(unique(data));
Addendum
You speak of items that reference the same object in memory. Such a thing does not happen when your array is initialised as a plain literal, but if you assign the same object to several array entries, then you get duplicate references, like so:
const obj = { id: 1, name: "" };
const data = [obj, obj];
This is not the same thing as:
const data = [{ id: 1, name: "" }, { id: 1, name: "" }];
In the second version you have two different references in your array.
I have assumed that you want to "catch" such duplicates as well. If you only consider duplicate what is presented in the first version (shared references), then this was asked before.
Basically I have got an object, which will be multi-dimensional and the properties could be named anything and it could have many dimensions.
At some point I will need to append/splice a property within this object, from code which won't know it's position.
So, an example object:
let obj = {
response: {
locations: {
data: [
0: Object,
1: Object,
2: Object,
]
}
},
endpoint: null
}
I need to splice out data.locations.data[1], the only information I have is the below array and the index. Obviously I will know the first property will be response.
['locations','data']
index: 1
Edit:
My mistake, the data property has an array value not an object!
You can use Array#reduce() and pass in obj.response as the start value to get at the nested parent which based on the array shown would be obj.response.locations.data.
Then splice() the indexed item in that parent or do whatever other modifications are needed
const arr = ['locations','data'],
index= 1,
obj = {
response: {
locations: {
data: [{id:1},{id:2}, {id:3}]
}
},
endpoint: null
}
const targetArr = arr.reduce((a,c)=> (a[c]), obj.response);
targetArr.splice(index,1);
console.log(obj)