The following code loops through a JavaScript object and collects only the properties that are arrays:
const building = this.building
let panoramaList = []
for (let key in building) {
const panoramas = building[key]
if (Array.isArray(panoramas)) {
panoramaList.push({ [key]: panoramas })
}
}
console.log(panoramaList)
In other words, it takes this:
{
name: '',
description: ''.
livingroom: Array[0],
study: Array[1],
bedroom: Array[0]
}
and turns it into this:
[
{ livingroom: Array[0] },
{ study: Array[1] },
{ bedroom: Array[0] }
]
However, what I need to produce is this:
{
livingroom: Array[0],
study: Array[1],
bedroom: Array[0]
}
How to accomplish that?
Change this :
const building = this.building
let panoramaList = []
for (let key in building) {
const panoramas = building[key]
if (Array.isArray(panoramas)) {
panoramaList.push({ [key]: panoramas })
}
}
console.log(panoramaList)
to this :
const building = this.building
let panoramaList = {}
for (let key in building) {
const panoramas = building[key]
if (Array.isArray(panoramas)) {
panoramaList[key]=panoramas
}
}
console.log(panoramaList)
Use Object.keys and try something like this:
var input = {} //...your input array
var keys = Object.keys(input);
var result = {};
keys.forEach(function (key) {
if (Array.isArray(input[key])) {
result[key] = input[key];
}
});
try this
var output = Object.keys(building).map(function(val){ return { val : building[val] } });
For the final output
var panoramaList = {}
Object.keys(building).forEach(function(val){
if ( Array.isArray(building[val] )
{
panoramaList[val] = building[val];
}
});
Make sure to define panoramaList as an object.
This works
var arrays = {
name: '',
description: '',
livingroom: ['1','www'],
study: ['2','sss'],
bedroom: ['3','aaa'],
Kitchen: ['4','bbb'],
}
const building = arrays
let panoramaList = {};
for (let key in building) {
const panoramas = building[key]
if (Array.isArray(panoramas)) {
panoramaList[key] = panoramas;
}
}
console.log(panoramaList);
https://jsbin.com/paqebupiva/1/edit?js,console,output
Rather than building a new object, you might just need to delete the unwanted properties from the object that you have:
var data = {
name: '',
description: '',
livingroom: [],
study: [1],
bedroom: [0]
};
Object.keys(data).forEach(function(key) {
if (!Array.isArray(data[key])) delete data[key];
})
document.write(JSON.stringify(data));
Related
I have an object Regions{} which stores multiple objects, following code block showing countryName : [regions,..,..]
Regions = { Afghanistan:["Badakhshan~BDS", "Badghis~BDG", "Baghlan~BGL"]
Albania:["Berat~01", "Dibër~09", "Durrës~02",]
}
Which giving me result like this:
Afghanistan: Array(n)
0: "Badakhshan~BDS"
1: "Badghis~BDG"
what I am trying to achive is :
Afghanistan: Array(n)
0:{value: "Badakhshan", lable: "BDS"}
1:{value: "Badghis", lable: "BDG"}
thanks in advance
PS: for the sake of some ruthless fellows following is the code what I have tried yet
let countries = CountryRegionData
let regions = {}
countries = countries.map(country => {
regions = {
...regions,
[country[0]]: country[2].split('|')
}
return {
value: country[1],
label: country[0]
}
})
console.log("countries",countries)
console.log("regions",regions)
let values = regions["Afghanistan"];
values = values.map(value =>{
return {
value: value,
lable: value
}
})
You can use split and map, this code is changing values in original object, if you want to build a new object you can use reduce instead of forEach
let Regions = {
Afghanistan: ["Badakhshan~BDS", "Badghis~BDG", "Baghlan~BGL"],
Albania: ["Berat~01", "Dibër~09", "Durrës~02", ]
}
Object.entries(Regions).forEach(([key,value])=>{
Regions[key] = value.map(data=>{
let [value,label] = data.split('~')
return {value,label}
})
})
console.log(Regions)
Do something like:
Regions.map(region => region.map(txt => {
const [val, lbl] = txt.split("~");
return { value: val, lable: lbl};
}));
Messy but gets the work done. Using nested forEach loops
var Regions = {
Afghanistan: ["Badakhshan~BDS", "Badghis~BDG", "Baghlan~BGL"],
Albania: ["Berat~01", "Dibër~09", "Durrës~02", ]
}
var ar = [];
Object.keys(Regions).forEach(function(e) {
Regions[e].forEach(function(k) {
var arr = k.split('~');
ar.push({
value: arr[0],
label: arr[1]
})
})
Regions[e] = ar;
ar = [];
})
console.log(Regions)
Use the map function to iterate the object.
Regions = {
Afghanistan: ["Badakhshan~BDS", "Badghis~BDG", "Baghlan~BGL"],
Albania: ["Berat~01", "Dibër~09", "Durrës~02", ]
};
const finalObject = Object.keys(Regions).map(region => {
return {
[region]: Regions[region].map(country => {
const [value, lable] = country.split("~");
return {
value,
lable
};
})
};
});
console.log(finalObject);
I have two objects, one is used to update the other, something like ETL Process.
const currentObject = {
myObject : [
{
'attribute1':'foo1',
'attribute2':'bar1',
'attribute3':'test1'
},
{
'attribute1':'foo2',
'attribute2':'bar2',
'attribute3':'test2'
},
{
'attribute1':'foo3',
'attribute2':'bar3',
'attribute3':'test3'
},
]
}
if the attribute3 value is "test1", then go to the other object and check for the test1 property and replace the currentObject with the new value
const updateObject = {
myObject : {
'test1':'newtest1',
'test2':'newtest2',
'test3':'newtest3'
}
}
update is done on currentObject attribute3 needs to use updateObject property as reference;
where currentObject attribute1="test1" should copy data from updateObject test1 so on:
Final value should be like:
const currentObject = {
myObject : [
{
'attribute1':'foo1',
'attribute2':'bar1',
'attribute3':'newtest1'
},
{
'attribute1':'foo2',
'attribute2':'bar2',
'attribute3':'newtest2'
},
{
'attribute1':'foo3',
'attribute2':'bar3',
'attribute3':'newtest3'
}
]
}
You can use forEach and Object.entries
Here idea is
First loop through each element in myObject array of currentObject
Now as in your structure you have value of currentObject as key in updateObject, so we check existence by updateObject.myObject[value]
If it's their we update currentObject else we keep it unchanged
const currentObject = {myObject : [{'attribute1':'foo1','attribute2':'bar1','attribute3':'test1'},{'attribute1':'foo2','attribute2':'bar2','attribute3':'test2'},{'attribute1':'foo3','attribute2':'bar3','attribute3':'test3'},]}
const updateObject = {myObject : {'test1':'newtest1','test2':'newtest2','test3':'newtest3'}}
currentObject.myObject.forEach(e => {
Object.entries(e).forEach(([key,value]) => {
if(updateObject.myObject[value]){
e[key] = updateObject.myObject[value]
}
})
})
console.log(currentObject)
We can use Array.reduce and search for the current element's (ele) attribute3 property in the updateObject.myObject.
If present then update it with the matching value from the updateObject.myObject else keep the old one :
const currentObject = {myObject : [{'attribute1':'foo1','attribute2':'bar1','attribute3':'test1'},{'attribute1':'foo2','attribute2':'bar2','attribute3':'test2'},{'attribute1':'foo3','attribute2':'bar3','attribute3':'test3'},]};
const updateObject = {myObject : {'test1':'newtest1','test2':'newtest2','test3':'newtest3'}};
function transformObject(currentObject, updateObject){
const out = currentObject.myObject.reduce((acc, ele) => {
ele.attribute3 = updateObject.myObject[ele.attribute3] ?
updateObject.myObject[ele.attribute3] :
ele.attribute3;
return acc.concat(ele);
}, []);
finalObj = {[Object.keys(currentObject)[0]] : out };
return finalObj;
}
console.log(transformObject(currentObject, updateObject));
This turns into a one-liner with the latest JavaScript language features:
const currentObject = {
myObject: [
{
'attribute1': 'foo1',
'attribute2': 'bar1',
'attribute3': 'test1'
},
{
'attribute1': 'foo2',
'attribute2': 'bar2',
'attribute3': 'test2'
},
{
'attribute1': 'foo3',
'attribute2': 'bar3',
'attribute3': 'test3'
},
]
}
const updateObject = {
myObject: {
'test1': 'newtest1',
'test2': 'newtest2',
'test3': 'newtest3'
}
}
const result = { myObject: currentObject.myObject.map(o => ({ ...o, ...{ 'attribute3': updateObject.myObject[o.attribute3] } })) };
console.log(result);
...and you also get immutability.
I am trying to filter data inside array object of array object, Please find below code for more information.
var data = [
{
name:'testdata1',
subdata:[{status:'fail'},{status:'success'}]
},
{
name:'testdata2',
subdata:[{status:'fail'},{status:'success'}]
}
]
Expected Data:
var successdata = [
{
name:'testdata1',
subdata:[status:'success'}]
},
{
name:'testdata2',
subdata:[status:'success'}]
}
];
var FailureData =[
{
name:'testdata1',
subdata:[{status:'fail'}]
},
{
name:'testdata2',
subdata:[{status:'fail'}]
}
];
I missed curly braces,So i am updating
Hope this helps.
const data = [{
name: 'testdata1', subdata: [{status: 'fail'}, {
status:
'success'
}]
},
{
name: 'testdata2', subdata:
[{status: 'success'}, {status: 'fail'}]
}
];
const filterData = (data, status) => data.reduce((acc, val) => {
const sub = val.subdata.map((v) => v.status === status ? ({ name: val.name, subdata: [v] }) : null).filter(f => f !== null);
return acc.concat(sub);
}, []);
const successData = filterData(data, 'success');
const failureData = filterData(data, 'fail');
console.log('successData', successData);
console.log('failureData', failureData);
You could map your arrays using Array.map():
var successData = data.map(item => ({name: item.name, subdata:[{status:'success'}]})
What I guess you want to do is filter the array based on subdata status.
I also guess that what subdata should have is just the status property and your code would be: var data = [{name:'testdata1',subdata:[{status:'fail'},{status:'success'}] }.
Then you want to look in the subdata array and find which data have success and failure in them.
So what you could be looking for is this:
var successData = data.filter(sdata => {
var successFlag=false;
sdata.subdata.forEach(subdata=>{
if (subdata.status==='success'){
successFlag = true;
}
}
return successFlag;
}
The same with the failureData.
For more information you could check the Array.prototype.filter function:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
P.S. As mentioned in a comment to your question as well, your subdata array cannot be an object with two of the same property
var data = [{name:'testdata1',subdata:[{status:'fail'}, {status:'success'}] },{name:'testdata2',subdata:[{status:'success'}, {status:'fail'}] }]
var successData = filterByStatus('success', data);
var failureData = filterByStatus('fail', data);
function filterByStatus(status, data) {
return data.map(d => {
var newObj = Object.assign({}, d);
newObj.subdata = newObj.subdata.filter(s => s.status === status);
return newObj;
});
}
console.log('successData', successData);
console.log('failureData', failureData);
one of possible ways to do what you want if you have one success property in your object
This is an object to be processed:
var q = {
email: {contains: "noname#hotmail.com"},
name: {contains: "someuser"}
};
I would like to go through each key of q and if the corresponding value is an object that has the property contains then replace it with $regex.
Related information can be found here: JavaScript: Object Rename Key
You can try the following way:
var q = {
email: {contains: "noname#hotmail.com"},
name: {contains: "someuser"}
};
for(var k in q){
if(q[k].hasOwnProperty('contains')){
Object.defineProperty(q[k], '$regex',
Object.getOwnPropertyDescriptor(q[k], 'contains'));
delete q[k]['contains'];
}
}
console.log(q);
for(const obj of Object.values(q)) {
obj.$regex = obj.contains;
delete obj.contains;
}
Just go over all values inside q and copy the contains property into the $regex property.
To iterate over object keys first you have to fetch them, here is one simple approach
const keys = Object.keys(q); // ["email", "name"]
Now iterate over the array which we got and perform regex testing;
keys.forEach(key => {
let value = q[key].contains;
// create $regex and assign value
// remove .contains
})
You can loop through the objects and first put current value of contains property in $regex and then delete the contains property.
Below is working code:
var q = {
email: {
contains: "noname#hotmail.com"
},
name: {
contains: "someuser"
}
};
for (var i of Object.values(q)) {
if (i.hasOwnProperty("contains")) {
i.$regex = i.contains;
delete i.contains;
}
}
console.log(q);
var q = {
email: {contains: "noname#hotmail.com"},
name: {contains: "someuser"}
};
Object.keys(q).forEach(k => {
if (typeof q[k].contains != 'undefined'){
q[k].$regex = q[k].contains;
delete q[k].contains;
}
})
console.log(q);
Other version using Es 6 features
const renameProp = (
oldProp,
newProp,
{ [oldProp]: old, ...others }
) => {
return {
[newProp]: old,
...others
};
};
let q = {
email: {contains: "noname#hotmail.com"},
name: {contains: "someuser"}
};
let newObj = {}
for (let propName in q) {
newObj[propName] = renameProp("contains","$regex",q[propName])
}
console.log(newObj)
var q = {
email: {
contains: "noname#hotmail.com"
},
name: {
contains: "someuser"
},
asdf: "asdf"
};
Object.keys(q).forEach(function(item, index) {
if (typeof q[item] == "object" && q[item].contains) {
q[item].$regex = q[item].contains;
delete q[item].contains;
}
})
This answer is already close, and there are some answers how to get unique values in an array (remove duplicates,)though I can't make it work for the case where it is about an array of objects, and the property that should be filtered is an array. Sorry, I am a JS newbie. Thanks for the help.
I have an array of objects like this
const posts = [
post1: {
id: 1,
title: 'One',
tags: ['tagA', 'tagB']
},
post2: {
id: 2,
title: 'Two',
tags: ['tagB', 'tagC']
},
post3: {
id: 3,
title: 'Three',
tags: ['tagB', tagC, tagD]
]
What I would need is an array of all unique tags ... in the case above with an expected output like this:
// [tagA, tagB, tagC, tagD]
EDIT / UPDATE
The key in the array of objects is used to manage the state of the react component... e.g.
constructor(props) {
super(props);
this.state = {
posts: []
};
}
...
updatePost = (key, updatedPost) => {
//1. Take copy of the current this.state.
const posts = {...this.state.texts};
//2. Update that state
posts[key] = updatedPost;
//3. Set that to state
const options = { encrypt: false }
putFile(postsFileName, JSON.stringify(posts), options)
.then(() => {
this.setState({
posts: posts
})
})
};
Assuming that the input is on [ {} , {} ] format:
You can use concat and map to flatten your array. Use new Set to get the unique values.
const posts = [{"id":1,"title":"One","tags":["tagA","tagB"]},{"id":2,"title":"Two","tags":["tagB","tagC"]},{"id":3,"title":"Three","tags":["tagB","tagC","tagD"]}];
var result = [...new Set([].concat(...posts.map(o => o.tags)))];
console.log(result);
If the variable is an object ( {a:{} , b:{} } ) , you can use Object.values to convert the object into an array.
const posts = {"post1":{"id":1,"title":"One","tags":["tagA","tagB"]},"post2":{"id":2,"title":"Two","tags":["tagB","tagC"]},"post3":{"id":3,"title":"Three","tags":["tagB","tagC","tagD"]}}
var result = [...new Set([].concat(...Object.values(posts).map(o => o.tags)))];
console.log(result);
You can reduce your posts and iterate over the tags and push those to the result that you haven't encountered already:
const posts = [
{
id: 1,
title: "One",
tags: ["tagA", "tagB"]
},
{
id: 2,
title: "Two",
tags: ["tagB", "tagC"]
},
{
id: 3,
title: "Three",
tags: ["tagB", "tagC", "tagD"]
}
];
const uniqueTags = posts.reduce((result, post) => {
post.tags.forEach(tag => {
if (!result.includes(tag)) {
result.push(tag);
}
});
return result;
}, []);
console.log(uniqueTags);
This is assuming you know that the array key is always 'tags'.
let filter = {};
let result = [];
posts.forEach(post => {
const tags = post['tags'];
tags.forEach(tag => {
if (!filter.hasOwnProperty(tag)) {
result.push(tag);
filter[tag] = true;
}
});
});
with jquery you can do something similar to this (not Tested):
var results = [];
$.each(myObject, function(key,valueObj){
var check.isArray(obj);
if(check){
alert(key + "/" + valueObj );
/*replace repeat*/
var sorted_check = check.slice().sort(); // You can define the comparing function here.
// JS by default uses a crappy string compare.
// (we use slice to clone the array so the
// original array won't be modified)
for (var i = 0; i < sorted_check.length - 1; i++) {
if (sorted_check[i + 1] == sorted_check[i]) {
results.push(sorted_check[i]);
}
}
}
});
and a good way with indexof:
Array.prototype.unique = function() {
var a = [];
for ( i = 0; i < this.length; i++ ) {
var current = this[i];
if (a.indexOf(current) < 0) a.push(current);
}
this.length = 0;
for ( i = 0; i < a.length; i++ ) {
this.push( a[i] );
}
return this;
}
Array.prototype.unique = function() {
var a = [];
for ( i = 0; i < this.length; i++ ) {
var current = this[i];
if (a.indexOf(current) < 0) a.push(current);
}
return a;
}
And Follow UP:
Array.prototype.unique = function(mutate) {
var unique = this.reduce(function(accum, current) {
if (accum.indexOf(current) < 0) {
accum.push(current);
}
return accum;
}, []);
if (mutate) {
this.length = 0;
for (let i = 0; i < unique.length; ++i) {
this.push(unique[i]);
}
return this;
}
return unique;
}
If you want to use a functional library like Ramda.js you can do this:
const posts = [
{
id: 1,
title: 'One',
tags: ['tagA', 'tagB'],
},
{
id: 2,
title: 'Two',
tags: ['tagB', 'tagC'],
},
{
id: 3,
title: 'Three',
tags: ['tagB', 'tagC', 'tagD'],
},
];
var unique = R.uniq(R.flatten(R.map(R.prop('tags'), posts)))
console.log(unique)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>