I have the following function:
populateClinicRoomSelect(object) {
var selectArray = [];
var options = [];
for(var key in object) {
if(object.hasOwnProperty(key)) {
options = {
value: object[key].id,
label: object[key].RoomName,
};
selectArray = selectArray.concat(options);
}
}
return selectArray;
}
The idea is that takes two defined fields from the object array and places it in a new array. It works fine. I also have a few more functions exactly the same to this except the 'id' field and 'RoomName' field are different field names. Is there any way to pass 'id' and 'RoomName' as function variables to define them in the function?
Sure, you can pass field names as arguments and use [arg] accessors as you already do with [key]:
function populateClinicRoomSelect(object, valueField, labelField) {
var selectArray = [];
var options = [];
for(var key in object) {
if(object.hasOwnProperty(key)) {
options = {
value: object[key][valueField],
label: object[key][labelField],
};
selectArray = selectArray.concat(options);
}
}
return selectArray;
}
const object = {
a: {
id: 1,
room: 'first room'
},
b: {
id: 2,
room: 'second room'
}
}
const result = populateClinicRoomSelect(object, 'id', 'room');
console.log(result)
You mean like this?
function populateClinicRoomSelect(object, value, label) {
value = value || "id"; // defaults value to id
label = label || "RoomName"; // defaults label to RoomName
var selectArray = [];
var options = [];
for(var key in object) {
if(object.hasOwnProperty(key)) {
options = {
value: object[key][value],
label: object[key][label],
};
selectArray = selectArray.concat(options);
}
}
return selectArray;
}
let obj = { 1: { id:1, RoomName: "Blue Lounge" }, 2: { id:2, RoomName: "Red Lounge" } }
console.log(populateClinicRoomSelect(obj, 'id', 'RoomName'));
Related
I have two identical objects with me
let a = {
title : "developer”,
startDate:{ month :’jan’}
}
let b = {
title :{
value: ""
} ,
startDate :{month:{value:””}}
}
i need to merge dynamically these two to get object like below
let c = {
title :{
value: "developer"
} ,
startDate:{
month:{ value:” jan”}}
}
You don't require object b because it's just a replica of object a with extra 'value' property.
You can traverse the complete a object and then deep copy the value in the b object.
I wrote a recursive method for this where you can traverse to the last level of the object and copy the value in another object.
function mergeObj(sourceObj, newObj) {
Object.keys(sourceObj).forEach(key => {
if (sourceObj[key] && typeof sourceObj[key] === 'object') {
newObj[key] = {};
mergeObj(sourceObj[key], newObj[key]);
} else {
// updating properties
newObj[key] = {};
newObj[key]['value'] = sourceObj[key];
}
});
}
let a = {
title : "developer",
startDate:{ month :'jan'}
};
let b = {};
mergeObj(a,b);
console.log(b);
You probably need to start by making both object have the same structure, and then run the deep merge. lodash's merge can help you with it
const newA = Object.entries(a).reduce((newObject, [key, value]) => ({
...newObject,
[key]: { value },
}, {}))
// newA looks now like
//
// {
// title: {
// value: "developer
// }
// }
let c = _.merge(a, b); // lodash merge for deep merge. Otherwise write your own
Here is a workaround for your problem:
let a = {
title : "developer",
startDate:{ month :'jan'}
}
let b = {
title :{
value: ''
} ,
startDate :{month:{value:''}}
}
var c = {};
c.startDate = {};
c.title = {};
c.startDate.month = {};
c.startDate.month.value = a.startDate.month;
c.title.value = a.title;
console.log("Merged object",c);
You can just implement a function that does this for you. Given your example:
let a = {
title: "developer",
startDate: { month: "jan" }
};
let b = {
title: {
value: ""
},
startDate: { month: { value: "" }}
};
You can use this to get the values:
const mergeObject = (a, b) => {
b.title.value = a.title;
b.startDate.month.value = a.startDate.month;
return b;
};
If you call now say let c = mergeObject(a, b) c will be
let c = {
title: {
value: "developer"
},
startDate: {
month: { value: "jan" }}
}
Of course this function can be modified to reflect your exact needs.
I have an object that looks like this:
{house_id+street_id+school_id: {...}, house_id2+street_id2+school_id2: {...}, ...}
So, each key of the object is a combination of a house_id a street_id and a school_id separated by '+' sign.
I want to be able to filter the object given a street_id, so for example, for the given object:
{40+30+20: { name: "john" }, 41+31+20: { name: "eli" } } and the street_id being 30, the returning object would be:
{40+30+20: "john"}
How can I do that filtering?
You can do it in the following way
let obj = {'40+30+20': { name: "john" }, '41+31+20': { name: "eli" } }
let result = Object.keys(obj).filter(e => e.match(/^.*\+30\+.*$/) != null).reduce((a, b) => {
a[b] = obj[b];
return a;
}, {});
console.log(result);
You can do something like this:
var data = {
'40+30+20': {
name: "john"
},
'41+31+20': {
name: "eli"
}
};
var search = '30';
var r = Object.keys(data).filter(function(key) {
return key.split('+').some(function(p) {
return p === search;
});
}).map(function(key) {
var o = {};
o[key] = data[key];
return o;
});
console.log(r);
Try with the filter function and a regular expression:
var myObj = {'40+30+20': { name: "john" }, '41+31+20': { name: "eli" } };
function filterByStreet(obj, streetId) {
var filteredKeys = Object.keys(obj).filter((key) => {
var patt = new RegExp("[^+]+[+]" + streetId + "[+][0-9]+");
return patt.test(key);
});
var outObj = {};
for(filteredKey of filteredKeys) {
outObj[filteredKey] = obj[filteredKey];
}
return outObj;
}
var filteredObj = filterByStreet(myObj, 30);
console.log(filteredObj);
I have an javascript array of object containing some parameters to be passed to custom class.
var classObjectDetails = [{
name: "objOne",
options: ["1","2"],
children: [{
name: "childOne_objOne",
options: null
children: [{
name: "childOne_childOne_objOne",
options: ["a", "b", "c", "d"],
}]
}, {
name: "childTwo_objOne",
options: null,
}]
}, {
name: "objTwo",
options: null,
}];
Above is sample object containing details. If i have a class like below,
class sampleClass {
constructor(objName, option) {
this.name = objName;
this.options = option;
this.children = [];
// Some other properties
}
// Some other functions
}
I want to write an efficient recursive function which in the end return me the array of sampleClass object.
objOne and objTwo being two object in array, with objOne having two children and so on as given in the classObjectDetails
You can create recursive function using forEach() loop and use data from each object in original array to create instance of your class that will have all methods of that class.
var data = [{"name":"objOne","options":["1","2"],"children":[{"name":"childOne_objOne","options":null,"children":[{"name":"childOne_childOne_objOne","options":["a","b","c","d"]}]},{"name":"childTwo_objOne","options":null}]},{"name":"objTwo","options":null}]
class sampleClass {
constructor(objName, option) {
this.name = objName;
this.options = option;
this.children = [];
}
getName() {
return this.name;
}
}
function create(data) {
var result = [];
data.forEach(function(e) {
var o = new sampleClass;
o.name = e.name;
o.options = e.options
if (e.children) {
var children = create(e.children)
if (children.length) o.children = children;
}
result.push(o)
})
return result;
}
var result = create(data);
console.log(result)
console.log(result[0].children[0].getName())
<script>
var classObjectDetails = [
{
name: "objOne",
options: ["1","2"],
children: [
{
name: "childOne_objOne",
options: null,
children: [
{
name: "childOne_childOne_objOne",
options: ["a", "b", "c", "d"],
}
]
},
{
name: "childTwo_objOne",
options: null,
}
]
},
{
name: "objTwo",
options: null,
}];
function parseJSONTosampleClass(classObjectDetail){
var sampleClasList = [];
for (var key in classObjectDetail) {
var child = classObjectDetail[key];
var obj = new sampleClass();
sampleClasList.push(obj);
obj.name = child["name"];
obj.options = child["options"];
obj.children = parseJSONTosampleClass(child["children"]);
}
return sampleClasList;
}
class sampleClass {
constructor(objName, option) {
this.name = objName;
this.options = option;
this.children = [];
}
}
parseJSONTosampleClass(classObjectDetails);
</script>
I've got an array of objects and I need a function that finds object an array by the objects property (id in example) and changes its other property (name in example). Currently my implementation looks like this:
var arrayOfObjects = [{
id: 1,
name: 'Alpha'
}, {
id: 2,
name: 'Bravo'
}];
var setNameById = function (id, newName) {
arrayOfObjects.filter(function(obj) {return obj.id === id;}).name = newName;
};
console.log(JSON.stringify(arrayOfObjects)); // initial array logged
setNameById(2, 'Charlie');
console.log(JSON.stringify(arrayOfObjects)); // initial array logged
I understand that the problem is in changing the object that is returned by filter and not initial one, but I haven't found implementations that give access to initial object in such a situation, is it possible or do I need to rethink the steps that led me to this point.
Use this instead of filter. Filter produce new array.
arrayOfObjects.forEach(function(v){
if (v.id == id) {v.name = newName}
});
Use Array#forEach over Array#filter
Note that == or === should be used to compare, = will assign the value!
Array#forEach with condition should be enough just to update existing array of object.
var arrayOfObjects = [{
id: 1,
name: 'Alpha'
}, {
id: 2,
name: 'Bravo'
}];
var setNameById = function(id, newName) {
var filtered = arrayOfObjects.filter(function(obj) {
return obj.id == id;
});
filtered.forEach(function(el) {
el.name = newName;
});
return filtered;
};
console.log(JSON.stringify(arrayOfObjects));
var filtered = setNameById(2, 'Charlie');
console.log(JSON.stringify(filtered));
Or use Array#map
var arrayOfObjects = [{
id: 1,
name: 'Alpha'
}, {
id: 2,
name: 'Bravo'
}];
var setNameById = function(id, newName) {
return arrayOfObjects.filter(function(obj) {
return obj.id == id;
}).map(function(el) {
el.name = newName;
return el;
});
};
console.log(JSON.stringify(arrayOfObjects));
var filtered = setNameById(2, 'Charlie');
console.log(JSON.stringify(filtered));
Filter returns an array. So will have to use index in your approach.
Your Approach
var arrayOfObjects = [{
id: 1,
name: 'Alpha'
}, {
id: 2,
name: 'Bravo'
}];
var setNameById = function(id, newName) {
arrayOfObjects.filter(function(obj) {
return obj.id = id;
})[0].name = newName;
};
console.log(JSON.stringify(arrayOfObjects)); // initial array logged
setNameById(2, 'Charlie');
console.log(JSON.stringify(arrayOfObjects));
array.find
If you are sure it will return only one value, use array.find
var arrayOfObjects = [{
id: 1,
name: 'Alpha'
}, {
id: 2,
name: 'Bravo'
}];
var setNameById = function(id, newName) {
arrayOfObjects.find(function(obj) {
return obj.id = id;
}).name = newName;
};
console.log(JSON.stringify(arrayOfObjects)); // initial array logged
setNameById(2, 'Charlie');
console.log(JSON.stringify(arrayOfObjects));
array.forEach
If there can be more than 1 object with same search key (id in this case), use array.forEach instead of array.filter and then loop over filtered array
var arrayOfObjects = [{
id: 1,
name: 'Alpha'
}, {
id: 2,
name: 'Bravo'
}];
var setNameById = function(id, newName) {
arrayOfObjects.forEach(function(obj) {
if(obj.id = id) obj.name = newName;
});
};
console.log(JSON.stringify(arrayOfObjects)); // initial array logged
setNameById(2, 'Charlie');
console.log(JSON.stringify(arrayOfObjects));
I have a JavaScript object:
var list = {
ListId: '',
Items: {}
};
What I want to do is to be able to add dynamic properties to Items property object. User can define properties with the same name but the logic should check if the property exists and if yes create same property name by adding a suffix or prefix (generated) but user will still see same property name.
Example:
var list = {
ListId: '',
Items: {
Name :{
Value: 'Some Value',
DisplayName: "Name"
},
Name1 :{
Value: 'Some Other Value',
DisplayName: "Name"
},
Name2 :{
Value: 'Some Third Value',
DisplayName: "Name"
}
}
};
How can I manage this object properties?
I managed to figure out how to add properties if they don't exist:
function addProperty(name) {
if (!list.Items.hasOwnProperty(name)) {
list.Items[name] = '';
}
};
First of all, your new property is an object, not a blank string, so that at least should have been
function addProperty(name) {
if (!list.Items.hasOwnProperty(name)) {
list.Items[name] = {};
}
};
Furthermore, you have all the methods right there you need, just create an else part and numerically increment the name until you find one that does not exist:
function addProperty(name) {
if (!list.Items.hasOwnProperty(name)) {
list.Items[name] = {};
}
else{
var i = 1;
while(list.Items.hasOwnProperty(name + i)){
i++;
}
list.Items[name + i] = {};
}
};
You could check if the wanted name is a keys of the item property. If true, then it could be used.
function checkIsFree(item) {
return !(item in list.Items);
}
var list = { ListId: '', Items: { Name: { Value: 'Some Value', DisplayName: "Name" }, Name1: { Value: 'Some Other Value', DisplayName: "Name" }, Name2: { Value: 'Some Third Value', DisplayName: "Name" } } };
document.write(checkIsFree('Name5') + '<br>'); // true
document.write(checkIsFree('Name2') + '<br>'); // false
Try this:
var indexes = {};
function addProperty(name, value) {
if (!list.Items.hasOwnProperty(name)) {
list.Items[name] = value;
} else {
indexes[name] = indexes[name]+1 || 1;
list.Items[name + indexes[name]] = value;
}
};
Code below shall perform desired action:
function addProperty(obj, name) {
if (!obj.Items.hasOwnProperty(name)) {
obj.Items[name] = '';
return true
}
return false
};
function addIndexedProperty(obj, name){
var i = 1;
var originName = name;
while (!addProperty(obj, name)){
name = originName + i;
i++;
}
return obj
}
var list = {
ListId: '',
Items: {}
};
addIndexedProperty(list, 'Name');
addIndexedProperty(list, 'Name');
addIndexedProperty(list, 'Name');
console.log(list['Items']); // Object {Name: "", Name1: "", Name2: ""}
Good Luck !
Use recursion to add suffix. Use hasOwnProperty to find if a key exists.
Algorithm
Function takes name,value and length as arguments. Length initially is 0.
When the supplied key already exists, it increments the length and checks if the (name+length) key exists.
If it does not exist, it recursively calls itself with the arguments (name+length,value,0). This will add the key to the list.
If the (name+length) key does not exist, the length is incremented and the the function is called with (name,value,length). This goes on.
If the key does not exist, it is simply added.
var list = {
ListId: '',
Items: {
Name: {
Value: 'Some Value',
DisplayName: "Name"
},
Name1: {
Value: 'Some Other Value',
DisplayName: "Name"
},
Name2: {
Value: 'Some Third Value',
DisplayName: "Name"
}
}
};
function addProperty(name, value, length = 0) {
if (list.Items.hasOwnProperty(name)) {
length++;
if (list.Items.hasOwnProperty(name + length)) {
return addProperty(name, value, length);
} else {
return addProperty(name + length, value, 0);
}
} else {
return list.Items[name] = value;
}
};
addProperty('this_argument_does_not_exist_yet', 'val');
addProperty('Name', 'val');
addProperty('Name', 'val');
addProperty('Name', 'val');
addProperty('Name1', 'val');
console.log(list);
document.getElementById('mypre').innerHTML = JSON.stringify(list,null,2);
<pre id="mypre"></pre>