I have an object like below
{
UserId: "",
BidderId: "",
"1stDomestic.BidderId": "",
"1stDomestic.UserId": "234",
"1stEmployee.CreatedDate": "",
"1stIndependent.UpdatedDate": "",
"1stIndependent.CreateDate": ""
}
The requirement is such that I need to group the dotted object keys and create the output as below
{
UserId: "",
BidderId: "",
1stDomestic: [
{
BidderId="",
UserId="234"
}
],
1stEmployee: [
{
CreatedDate=""
}
],
1stIndependent: [
{
UpdatedDate="",
CreatedDate=""
}
],
lstDomestic.BidderId = "",
1stDomestic.UserId="234",
1stEmployee.CreatedDate="",
1stIndependent.UpdatedDate=""
1stIndependent.CreateDate=""
}
I have tried to achieve this using couple of approaches.
Here requestedData is the object
Approach 1
for (let prop in requestedData) {
if (prop.indexOf(".") > -1) {
mainKey[prop.split(".").pop()] = requestedData[prop];
requestedData[prop.substr(0, prop.indexOf("."))] = [mainKey];
}
}
console.log(requestedData)
The above approach gives me the structure, but the array data reflects the same for all.
1stDomestic: [
{
BidderId="",
UserId="234",
CreatedDate="",
UpdatedDate=""
}
],
1stEmployee: [
{
BidderId="",
UserId="234",
CreatedDate="",
UpdatedDate=""
}
],
1stIndependent: [
{
BidderId="",
UserId="234",
CreatedDate="",
UpdatedDate=""
}
]
Approach 2
for (let prop in requestedData) {
if (prop.indexOf(".") > -1) {
arr.push({
newProp: prop.substr(0, prop.indexOf(".")), //-->1
mainKey: prop.split(".").pop(), // --> 2
value: requestedData[prop] // -->3
});
}
}
console.log(Object.assign(requestedData, groupData(arr));
groupData(arrVal) {
let key = "newProp";
return resData.reduce((previous, current) => {
previous[current[key]] && previous[current[key]].length != 0
? previous[current[key]].push(current)
: (previous[current[key]] = new Array(current));
return previous;
}, {});
}
The above approach groups the data based on the keys, but then it creates and individual arrays of object with properties as in 1,2 and 3
I expect this to be the way as mentioned above.
I am kind of now in a fix and trying to figure that out.
I am new to this forum, asking question, please bear if I somehow made this question too lengthy and intuitive.
Help would be appreciated
You can first create an object of nested objects based on the keys using reduce and then merge your original object with the nested object to get your final result:
const data = {
UserId: "",
BidderId: "",
"1stDomestic.BidderId": "",
"1stDomestic.UserId": "234",
"1stEmployee.CreatedDate": "",
"1stIndependent.UpdatedDate": "",
"1stIndependent.CreateDate": ""
};
const nested = Object.entries(data)
.filter(([k, v]) => k.includes('.'))
.reduce((acc, [k, v]) => {
const [parent, child] = k.split('.');
acc[parent] = acc[parent] || [{}];
acc[parent][0][child] = v;
return acc;
}, {});
const result = { ...data, ...nested};
console.log(result);
You can use below solution.
var requestedData = {
UserId: "",
BidderId: "",
"lstDomestic.BidderId" : "",
"lstDomestic.UserId":"234",
"lstEmployee.CreatedDate":"",
"lstIndependent.UpdatedDate":"",
"lstIndependent.CreateDate":""
}
var newData = [];
var previousKey = "";
for (let prop in requestedData) {
if (prop.indexOf(".") > -1) {
if(previousKey != prop.substr(0, prop.indexOf(".")))
{
ainKey = [];
}
previousKey = prop.substr(0, prop.indexOf("."))
mainKey[prop.split(".").pop()] = requestedData[prop];
newData[prop.substr(0, prop.indexOf("."))] = [mainKey];
}
}
console.log(newData)
you can try live working demo.
https://jsfiddle.net/cakp8z6n/4/
If you call your original object obj, this should work:
Object.keys(obj).forEach(key => {
if (key.includes('.')) {
const [base, suffix] = key.split('.');
obj[base] = obj[base] || [{}];
obj[base][0][suffix] = obj[key];
}
});
console.log(obj);
Or, if you don't want to modify the original object, but make a modified copy instead:
const obj2 = {};
Object.keys(obj).forEach(key => {
obj2[key] = obj[key];
if (key.includes('.')) {
const [base, suffix] = key.split('.');
obj2[base] = obj2[base] || [{}];
obj2[base][0][suffix] = obj[key];
}
});
let orgObj={
UserId: "",
BidderId: "",
"lstDomestic.BidderId": "",//difference 1st and Ist
"1stDomestic.UserId": "234",//difference 1st and Ist
"1stEmployee.CreatedDate": "",
"1stIndependent.UpdatedDate": "",
"1stIndependent.CreateDate": ""
};
let complexKeys = Object.keys(orgObj).filter(key=>{return key.match(/.+\..+/)})
So complexKeys now ["lstDomestic.BidderId", "1stDomestic.UserId", "1stEmployee.CreatedDate", "1stIndependent.UpdatedDate", "1stIndependent.CreateDate"]
complexKeys.forEach(eachCompleKey=>{debugger;
let firstPart= eachCompleKey.match(/^(\w+)\./)[1];
let lastPart= eachCompleKey.match(/\.(\w+)$/)[1];
if(orgObj[firstPart]==undefined){debugger;
orgObj[firstPart]=[{}];
}
orgObj[firstPart][0][lastPart]=orgObj[eachCompleKey]
})
console.log(orgObj)
Output
{
"UserId": "",
"BidderId": "",
"lstDomestic.BidderId": "",
"1stDomestic.UserId": "234",
"1stEmployee.CreatedDate": "",
"1stIndependent.UpdatedDate": "",
"1stIndependent.CreateDate": "",
"lstDomestic": [
{
"BidderId": ""
}
],
"1stDomestic": [
{
"UserId": "234"
}
],
"1stEmployee": [
{
"CreatedDate": ""
}
],
"1stIndependent": [
{
"UpdatedDate": "",
"CreateDate": ""
}
]
}
You can try something like below.
let obj = {
UserId: "",
BidderId: "",
"lstDomestic.BidderId": "",
"1stDomestic.UserId": "234",
"1stEmployee.CreatedDate": "",
"1stIndependent.UpdatedDate": "",
"1stIndependent.CreateDate": ""
};
const res = Object.keys(obj).reduce((acc, mainKey) => {
let [key1, key2] = mainKey.split(".");
if (key2 && acc[key1]) {
acc[key1][0] = { ...acc[key1][0],
...{
[key2]: obj[mainKey]
}
}
} else if (key2) {
acc[key1] = [{
[key2]: obj[mainKey]
}];
} else {
acc[key1] = obj[key1];
}
return acc;
}, {})
const finalResult = { ...obj,
...res
};
console.log(finalResult)
So this code will do it, but I'm confused why you want it in this format. It seems like it would make more sense to have 1stDomestic, 1stEmployee, and 1stIndependent be their own objects rather than single element arrays. It just requires you to do more work later to access the data!
var requestedData = {
UserId: "",
BidderId: "",
"lstDomestic.BidderId" : "",
"lstDomestic.UserId":"234",
"lstEmployee.CreatedDate":"",
"lstIndependent.UpdatedDate":"",
"lstIndependent.CreateDate":""
}
let output = {};
for (let prop in requestedData) {
// Check to see if this is a "blah.thing" property
if (prop.includes(".")) {
let props = prop.split(".");
// Check to see if we've added the array already
if (output[props[0]])
output[props[0]][0][props[1]] = requestedData[prop];
else
// ES 2015 baby!
output[props[0]] = [{[props[1]]: requestedData[prop]}]
}
// If it's not then just add it normally
else
output[prop] = requestedData[prop];
}
console.log(output);
Related
Let's assume I have the following array:
[
"About.vue",
"Categories/Index.vue",
"Categories/Demo.vue",
"Categories/Flavors.vue"
]
We use the Index.vue in each sub-folder to act as the parent of that folder. That means the above would look like:
[
{
name: "About",
children: []
},
{
name: "Categories",
children:
[
{
name: "Index.vue",
children: []
},
{
name: "Demo.vue",
children: []
},
{
name: "Flavors.vue",
children: []
}
]
}
]
I was able to get it working slightly by using the following tutorial: https://joelgriffith.net/array-reduce-is-pretty-neat/
However, the thing about that is that it is a root object with a property for each file, as opposed to an array with an object for each file.
The following code produces the intended output:
let paths = [
"About.vue",
"Categories/Index.vue",
"Categories/Demo.vue",
"Categories/Flavors.vue"
];
let helper = {
index: -1,
name: ""
};
function treeify(files) {
var fileTree = [];
function mergePathsIntoFileTree(prevDir, currDir, i, filePath) {
helper.name = currDir;
helper.index = i;
if (helper.index == 0) {
let index = prevDir.findIndex(x => x.name == helper.name);
if (index < 0) {
prevDir.push({
name: helper.name,
children: []
});
}
return prevDir;
}
if (helper.index >= 0) {
let obj = {
name: currDir,
children: []
};
prevDir[helper.index].children.push(obj);
helper.index = i;
helper.name = currDir;
}
}
function parseFilePath(filePath) {
var fileLocation = filePath.split('/');
// If file is in root directory, eg 'index.js'
if (fileLocation.length === 1) {
fileTree[0] = {
name: fileLocation[0],
children: []
};
} else {
fileLocation.reduce(mergePathsIntoFileTree, fileTree);
}
}
files.forEach(parseFilePath);
return fileTree;
}
console.log(treeify(paths));
However, it fails on the following input:
let paths = [
"About.vue",
"Categories/Index.vue",
"Categories/Demo.vue",
"Categories/Flavors.vue",
"Categories/Types/Index.vue",
"Categories/Types/Other.vue"
];
Does anyone know a solution to get it working for further nested lists of paths?
You can create this structure using forEach method to loop each path and split it to array on /, then you can also use reduce method to create nested objects.
let paths = ["About.vue","Categories/Index.vue","Categories/Demo.vue","Categories/Flavors.vue","Categories/Types/Index.vue","Categories/Types/Other.vue"];
let result = [];
let level = {result};
paths.forEach(path => {
path.split('/').reduce((r, name, i, a) => {
if(!r[name]) {
r[name] = {result: []};
r.result.push({name, children: r[name].result})
}
return r[name];
}, level)
})
console.log(result)
So, first off, I am going to assume this is in Node.js, second, I am currently at home so I don't have access to node.js at the moment so I had no real way of testing the code, however the following code should work.
What you need to do is check the contents of the folder and then make a check to see if an item in the folder is a directory or not, if true, call the function again with the new path (a.k.a. recursion).
So first you start by reading the folder, add each item's name to the .name property of the object, then you check if it's a folder or not, if it is, recursive for that path. Keep returning an array of objects back (this will be added to the .children property.
var fs = require('fs');
var filetree = DirToObjectArray('path/to/folder/');
function DirToObjectArray(path) {
var arr = [];
var content = fs.readdirSync(path, { withFileTypes: true });
for (var i=0; i< content.length; i++) {
var obj = new Object({
name: "",
children: []
});
obj.name = content[i].name;
if (content[i].isDirectory()) {
obj.children = DirToObjectArray(path + content[i].name + "/");
}
arr.push(obj);
}
return arr;
}
If you are not using node.js but in-browser javascript, I can't help you with that
You could take an iterative approach for every found name part and get an object and return the children for the next search.
var paths = ["About.vue", "Categories/Index.vue", "Categories/Demo.vue", "Categories/Flavors.vue", "Categories/Types/Index.vue", "Categories/Types/Other.vue"],
result = paths.reduce((r, p) => {
var names = p.split('/');
names.reduce((q, name) => {
var temp = q.find(o => o.name === name);
if (!temp) q.push(temp = { name, children: [] });
return temp.children;
}, r);
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I went with #Nenad Vracar's answer (and upvoted, thank you!), but I also had the need to allow duplicate filenames in my use case. I just wanted to share how I did that.
let paths = ["About.vue","Categories/Index.vue","Categories/Demo.vue","Categories/Flavors.vue","Categories/Types/Index.vue","Categories/Types/Other.vue","Categories/Types/Other.vue","Categories/Types/Other.vue"];
let result = [];
let level = {result};
paths.forEach(path => {
path.split('/').reduce((r, name, i, a) => {
if(!r[name]) {
r[name] = {result: []};
r.result.push({name, children: r[name].result});
} else if (i === a.length - 1) {
// Allow duplicate filenames.
// Filenames should always be at the end of the array.
r.result.push({name, children: []});
}
return r[name];
}, level)
})
console.log(result)
The following solution was derived from #nenad-vracar's answer. One shortcoming with his answer is that if a path contains "result", the code will fail. A simple workaround would be to rename "result" to "", that is, include characters that cannot appear in a path.
export interface IPathNode {
name: string;
children: IPathNode[];
path: IPath | null;
}
export interface IPath {
key: string;
directory: boolean;
}
interface IPathLevel {
// ["<result>"]: IPathNode[];
[key: string]: IPathLevel | IPathNode[];
}
export const createPathTree = (paths: IPath[]): IPathNode | null => {
const level: IPathLevel = { ["<result>"]: [] as IPathNode[] };
paths.forEach((path) => {
path.key.split("/").reduce(
((
currentLevel: IPathLevel,
name: string,
index: number,
array: string[]
) => {
if (!currentLevel[name]) {
currentLevel[name] = { ["<result>"]: [] };
(currentLevel["<result>"] as IPathNode[]).push({
name,
children: (currentLevel[name] as IPathLevel)[
"<result>"
] as IPathNode[],
/* Attach the path object to the leaf node. */
path: index === array.length - 1 ? path : null,
});
}
return currentLevel[name];
}) as any,
level
);
});
const finalArray = level["<result>"] as IPathNode[];
return finalArray.length > 0 ? finalArray[0] : null;
};
console.log(
JSON.stringify(
createPathTree([
{
key: "/components/button.tsx",
directory: false,
},
{
key: "/components/checkbox.tsx",
directory: false,
},
{
key: "/result",
directory: true,
},
]),
null,
4
)
);
Output:
{
"name": "",
"children": [
{
"name": "components",
"children": [
{
"name": "button.tsx",
"children": [],
"path": {
"key": "/components/button.tsx",
"directory": false
}
},
{
"name": "checkbox.tsx",
"children": [],
"path": {
"key": "/components/checkbox.tsx",
"directory": false
}
}
],
"path": null
},
{
"name": "result",
"children": [],
"path": {
"key": "/result",
"directory": true
}
}
],
"path": null
}
How do we check the keys and compare it to the data object , if one or more keys from the keys array does not exist in object data or if it exist or key exists and the key value has no value or null or undefined then return false else return true.
For example keys has a key summary and it exists on object data but the value is empty so it should return false;
I've tried Object.keys and used includes but cant seem to work it out, maybe someone has an idea. Thanks.
#currentCode
const sample = Object.entries(sampleOject).some((value) => {
return keys.includes(value[0]) ? false : (value[1] === null || value[1] === "");
})
Thanks.
#keys
const keys = [
'summary',
'targetRecdate',
'majorPositiveAttributes',
'generalRealEstateConcernsorChallenges',
'terminationPayment',
'effectiveDate',
'brokerCommission',
'brokerRebate',
'netEffectiveBrokerCommission']
#sample object data
{
"dealDispositionType": "A",
"majorPositiveAttributes": "a",
"terminationPayment": "31",
"netEffectiveBrokerCommission": -12189,
"brokerCommission": "123",
"brokerRebate": "12312",
"isPharmacyRestriction": 0,
"periodOfRestriction": null,
"pharmacyRestrictionDate": null,
"targetRecdate": "2022-10-20",
"isLandLordConsent": false,
"summary: ""
}
You could use every() with hasOwnProperty and additional checks for empty strings etc
const result = keys.every(key => {
return data.hasOwnProperty(key) && data[key] !== ''
}, {});
const keys = [
'summary',
'targetRecdate',
'majorPositiveAttributes',
'generalRealEstateConcernsorChallenges',
'terminationPayment',
'effectiveDate',
'brokerCommission',
'brokerRebate',
'netEffectiveBrokerCommission'
];
const data = {
"dealDispositionType": "A",
"majorPositiveAttributes": "a",
"terminationPayment": "31",
"netEffectiveBrokerCommission": -12189,
"brokerCommission": "123",
"brokerRebate": "12312",
"isPharmacyRestriction": 0,
"periodOfRestriction": null,
"pharmacyRestrictionDate": null,
"targetRecdate": "2022-10-20",
"isLandLordConsent": false,
"summary": ""
};
const result = keys.every(key => {
return data.hasOwnProperty(key) && data[key] !== ''
}, {});
console.log(result); // False
I just optimized your code.
const sample = Object.entries(sampleOject).map(([key, value]) => {
return keys.includes(key) ? value ? true : false : false;
})
...
const keys = [
'summary',
'targetRecdate',
'majorPositiveAttributes',
'generalRealEstateConcernsorChallenges',
'terminationPayment',
'effectiveDate',
'brokerCommission',
'brokerRebate',
'netEffectiveBrokerCommission']
const obj = {
"dealDispositionType": "A",
"majorPositiveAttributes": "a",
"terminationPayment": "31",
"netEffectiveBrokerCommission": -12189,
"brokerCommission": "123",
"brokerRebate": "12312",
"isPharmacyRestriction": 0,
"periodOfRestriction": null,
"pharmacyRestrictionDate": null,
"targetRecdate": "2022-10-20",
"isLandLordConsent": false,
"summary": "test"
}
let arr = [];
const result = Object.entries(obj).map(([key, val]) => {
if (keys.includes(key)) {
if ((val !== '') && (val !== 'undefined') && (val !== 'null') ) {
return true;
} else {
return false;
}
} else {
return false;
}
})
const getValue = result.includes(true);
console.log(getValue)
My approach would be to check whether all keys are present in data with the help of .every.
Also non-strict != will check if certain key contain neither null nor undefined
const keys = [
'summary',
'targetRecdate',
'majorPositiveAttributes',
'generalRealEstateConcernsorChallenges',
'terminationPayment',
'effectiveDate',
'brokerCommission',
'brokerRebate',
'netEffectiveBrokerCommission'];
const data = {
"dealDispositionType": "A",
"majorPositiveAttributes": "a",
"terminationPayment": "31",
"netEffectiveBrokerCommission": -12189,
"brokerCommission": "123",
"brokerRebate": "12312",
"isPharmacyRestriction": 0,
"periodOfRestriction": null,
"pharmacyRestrictionDate": null,
"targetRecdate": "2022-10-20",
"isLandLordConsent": false,
"summary": ""
};
const check = (obj, keys) => keys.every((key) =>
key in obj && obj[key] != undefined);
console.log(check(data, keys));
According to mdn,
const car = { make: 'Honda', model: 'Accord', year: 1998 };
console.log('make' in car); // output: true
I have an object with details - name, email, contact with unique ID
{
email_IcWDC6iyNzsQe9sPss4Yy: "xyz#gmail.com"
email_QVXeOX1vijCtpx8mdD662: "abc#gmail.com"
mobile_IcWDC6iyNzsQe9sPss4Yy: "223"
mobile_QVXeOX1vijCtpx8mdD662: "122"
name_IcWDC6iyNzsQe9sPss4Yy: "mp"
name_QVXeOX1vijCtpx8mdD662: "pp"
}
for example: name_QVXeOX1vijCtpx8mdD662 this contains name_UniqueID but remains same for one set of form for name, email, mobile. These values are taken from as many forms generated in the frontend, form has unique Id and that has been pass to their fields, so how can I make a new collection of objects containing a name, email, mobile for a particular unique id as given.
example:
[
{
id: "IcWDC6iyNzsQe9sPss4Yy"
name: "mp",
email: "",
mobile_no: "",
},
{
id: "QVXeOX1vijCtpx8mdD662"
name: "pp",
email: "",
mobile_no: "",
},
]
One way of doing it:
const d = {
email_IcWDC6iyNzsQe9sPss4Yy: "xyz#gmail.com",
email_QVXeOX1vijCtpx8mdD662: "abc#gmail.com",
mobile_IcWDC6iyNzsQe9sPss4Yy: "223",
mobile_QVXeOX1vijCtpx8mdD662: "122",
name_IcWDC6iyNzsQe9sPss4Yy: "mp",
name_QVXeOX1vijCtpx8mdD662: "pp"
};
const result = Object.values(
Object.entries(d).reduce((acc, [k, v]) => {
const [field, id] = k.split("_", 2);
if (!acc[id]) acc[id] = {id};
acc[id][field] = v;
return acc;
}, {})
);
console.log(result);
const input= {
email_IcWDC6iyNzsQe9sPss4Yy: "xyz#gmail.com",
email_QVXeOX1vijCtpx8mdD662: "abc#gmail.com",
mobile_IcWDC6iyNzsQe9sPss4Yy: "223",
mobile_QVXeOX1vijCtpx8mdD662: "122",
name_IcWDC6iyNzsQe9sPss4Yy: "mp",
name_QVXeOX1vijCtpx8mdD662: "pp"
}
const output=[];
for(let key in input||{}){
if(key.startsWith('name_')){
const id =key.replace('name_','');
const obj={
id,
name:input[key],
email:input[`email_${id}`],
mobile:input[`mobile_${id}`]
};
output.push(obj);
}
}
console.log('output json', output)
you can use dependecies called UUID or NanoId from NPM. this dependencies can be used for an unique ID.
to apply it use:
const idVar = uuidv4() || nanoid();
const obj = {
['id_' + idVar]: 'abcdefg2312',
['name_' + idVar]: "pp",
['email_' + idVar]: "",
['mobileNo_' + idVar]: "",
}
Not very efficient, but could be a sol:
const parentObj = {
email_IcWDC6iyNzsQe9sPss4Yy: "xyz#gmail.com",
email_QVXeOX1vijCtpx8mdD662: "abc#gmail.com",
mobile_IcWDC6iyNzsQe9sPss4Yy: "223",
mobile_QVXeOX1vijCtpx8mdD662: "122",
name_IcWDC6iyNzsQe9sPss4Yy: "mp",
name_QVXeOX1vijCtpx8mdD662: "pp"
};
let resultArr = [];
for (const key in parentObj) {
const template = {
id:"",
name:"",
email:"",
mobile:"",
};
let [prop,uid] = key.split("_");
if(!resultArr[uid]){
template.id = uid;
resultArr[uid] = template;
}
resultArr[uid][prop] = parentObj[key];
}
console.log(resultArr);
I am trying to get the change object from two objects using typescript in angular.
For example
this.productPreviousCommand = {
"id": "60f910d7d03dbd2ca3b3dfd5",
"active": true,
"title": "ss",
"description": "<p>ss</p>",
"category": {
"id": "60cec05df64bde4ab9cf7460"
},
"subCategory": {
"id": "60cec18c56d3d958c4791117"
},
"vendor": {
"id": "60ced45b56d3d958c479111c"
},
"type": "load_product_success"
}
model = {
"active": true,
"title": "ss",
"description": "<p>ss sss</p>",
"category": "60cec05df64bde4ab9cf7460",
"subCategory": "60cec18c56d3d958c4791117",
"vendor": "60ced45b56d3d958c479111c",
"tags": []
}
Now the difference between two objects are description: "<p>hello hello 1</p>". So I want to return {description: "<p>hello hello 1</p>"}
I used lodash https://github.com/lodash/lodash
import { transform, isEqual, isObject, isArray} from 'lodash';
function difference(origObj, newObj) {
function changes(newObj, origObj) {
let arrayIndexCounter = 0
return transform(newObj, function (result, value, key) {
if (!isEqual(value, origObj[key])) {
let resultKey = isArray(origObj) ? arrayIndexCounter++ : key
result[resultKey] = (isObject(value) && isObject(origObj[key])) ? changes(value, origObj[key]) : value
}
})
}
return changes(newObj, origObj)
}
This library is not working for me, it returns the whole object using this code const differenc = difference(this.productPreviousCommand, model);
The output of above code is
{
active: true
description: "<p>hello hello 1</p>"
id: "60f8f29dd03dbd2ca3b3dfd1"
title: "hello"
}
Try this function
differenceInObj(firstObj: any, secondObj: any): any {
let differenceObj: any = {};
for (const key in firstObj) {
if (Object.prototype.hasOwnProperty.call(firstObj, key)) {
if(firstObj[key] !== secondObj[key]) {
differenceObj[key] = firstObj[key];
}
}
}
return differenceObj;
}
You can check loop through each key of the first object and compare it with the second object.
function getPropertyDifferences(obj1, obj2) {
return Object.entries(obj1).reduce((diff, [key, value]) => {
// Check if the property exists in obj2.
if (obj2.hasOwnProperty(key)) {
const val = obj2[key];
// Check if obj1's property's value is different from obj2's.
if (val !== value) {
return {
...diff,
[key]: val,
};
}
}
// Otherwise, just return the previous diff object.
return diff;
}, {});
}
const a = {
active: true,
description: '<p>hello</p>',
id: '60f8f29dd03dbd2ca3b3dfd1',
title: 'hello',
};
const b = {
active: true,
description: '<p>hello hello 1</p>',
id: '60f8f29dd03dbd2ca3b3dfd1',
title: 'hello',
};
const c = {
active: true,
description: '<p>hello hello 2</p>',
id: '60f8f29dd03dbd2ca3b3dfd1',
title: 'world',
};
console.log(getPropertyDifferences(a, b));
console.log(getPropertyDifferences(b, c));
function difference(origObj, newObj) {
const origObjKeyList = Object.keys(origObj),
newObjKeyList = Object.keys(newObj);
// if objects length is not same
if (origObjKeyList?.length !== newObjKeyList?.length) {
return;
}
// if object keys some difference in keys
if (Object.keys(origObj).filter((val) => !Object.keys(newObj).includes(val))?.length) {
return;
}
return Object.entries(origObj).reduce(
(acc, [key, value]) => (newObj[key] !== value ? { ...acc, ...{ [key]: newObj[key] } } : acc),
[]
);
}
const a = {
active: true,
description: '<p>hello</p>',
id: '60f8f29dd03dbd2ca3b3dfd1',
title: 'hello',
};
const b = {
active: true,
description: '<p>hello hello 1</p>',
id: '60f8f29dd03dbd2ca3b3dfd1',
title: 'hello',
};
console.log(difference(a, b));
You can try this code.
function difference(origObj, newObj) {
const origObjKeyList = Object.keys(origObj),
newObjKeyList = Object.keys(newObj);
// if objects length is not same
if (origObjKeyList?.length !== newObjKeyList?.length) {
return;
}
// if object keys is not same
if (Object.keys(origObj).filter((val) => !Object.keys(newObj).includes(val))?.length) {
return;
}
return Object.entries(origObj).reduce(
(acc, [key, value]) => (newObj[key] !== value ? { ...acc, ...{ [key]: newObj[key] } } : acc),
[]
);
}
I am creating some objects from JSON and I would like to make an empty copy of an object. I would have all the same properties but empty values. What are some good ways of doing this?
Right now I am doing it as follows but would like it to be dynamic from the objects I create from the JSON I receive.
var myObject = { "Address": { "Address1": "", "Address2": "", "Address3": "", "Address4": "", "City": "", "": "", "": "", "Country": "", "Id": -1, "LastModified": "", "PostBackAction": null }, "Id": -1, "Amenities": "", "Directions": "", "LastModified": "", "LocalAttractions": "", "LocalLodging": "", "LocalRestaraunts": "", "Name": "", "Pictures": "", "Prices": "", "Region": 0, "PostBackAction": null };
A possible solution that doesn't work because it copies the values.
var myObject = JSON.parse(JSON.stringify(objectToBeCopied));
You could use a function that creates a copy of the object structure and uses a default value for each data type:
function skeleton(source, isArray) {
var o = Array.isArray(source) ? [] : {};
for (var key in source) {
if (source.hasOwnProperty(key)) {
var t = typeof source[key];
o[key] = t == 'object' ? skeleton(source[key]) : { string: '', number: 0, boolean: false }[t];
}
}
return o;
}
Demo: http://jsfiddle.net/Guffa/ym6ZJ/
var getCopy = function(objectToCopy){
var copy = {};
for(var prop in myObject){
if(typeof(objectToCopy[prop])==="object"){
copy[prop]= getCopy(objectToCopy[prop]);
}
else{
copy[prop]=null;
}
}
return copy;
}
Hope this is what you were looking for:
var myObject = function(){
this.address = {
'Address1': '',
'Address2': '',
'Address3': '',
'Address4': '',
'City': '',
'Country': '',
'Id': 0,
'LastModified': '',
'PostBackAction': null
};
this.Id = -1;
this.Amenities = '';
this.Directions = '';
this.LastModified = '';
this.LocalAttractions = '';
this.LocalLodging = '';
this.LocalRestaraunts = '';
this.Name = '';
this.Pictures = '';
this.Prices = '';
this.Region = 0;
this.PostBackAction = null;
}
// create two new objects
var objectOne = new myObject();
var objectTwo = new myObject();
console.log(objectOne);
//modify the first
objectOne.address.Address1 = 'Lol Street';
console.log(objectOne);
//notice the second one was not changed
console.log(objectTwo);