Make New Array which is combination of other Two - javascript

I Have Two Array, One is normal one where dates values are being stored
var = [
"2022-05-01",
"2022-05-02",
"2022-05-03",
"2022-05-04",
"2022-05-05",
"2022-05-06",
"2022-05-07",
"2022-05-08",
"2022-05-09",
"2022-05-10",
"2022-05-11",
"2022-05-12",
"2022-05-13",
"2022-05-14",
"2022-05-15",
"2022-05-16",
"2022-05-17",
"2022-05-18",
"2022-05-19",
"2022-05-20",
"2022-05-21",
"2022-05-22",
"2022-05-23",
"2022-05-24",
"2022-05-25",
"2022-05-26",
"2022-05-27",
"2022-05-28",
"2022-05-29",
"2022-05-30"
]
The other one is objects of Array where two objects are present
var b = [
{
"k_id": "6dcb67eb-1c8a-4239-9446-f9d8f6a68086",
"v_id": "aacc1765-a1d3-43c3-8233-beae19d258e5",
"key": "Testing",
"value": "999",
"start_date": "2022-05-06T00:00:00.000Z",
"end_date": "2022-05-06T00:00:00.000Z"
},
{
"k_id": "6dcb67eb-1c8a-4239-9446-f9d8f6a68086",
"v_id": "ad95cc4a-ec72-4d6e-a452-f519358f265d",
"key": "Testing",
"value": "189",
"start_date": "2022-05-08T00:00:00.000Z",
"end_date": "2022-05-`enter code here`08T00:00:00.000Z"
}
]
My Requirement is to Convert new array into like this
[
{
"value": "",
"value_id": "",
"date": "2022-05-01"
},
{
"value": "",
"value_id": "",
"date": "2022-05-02"
},
{
"value": "",
"value_id": "",
"date": "2022-05-03"
},
{
"value": "",
"value_id": "",
"date": "2022-05-04"
},
{
"value": "",
"value_id": "",
"date": "2022-05-05"
},
{
"value": "999",
"value_id": "48138929-6848-4ffe-86ce-183c75d021b4",
"date": "2022-05-06"
},
{
"value": "",
"value_id": "",
"date": "2022-05-07"
},
{
"value": "189",
"value_id": "06c4f66f-efae-4981-bebd-6734addab4a5",
"date": "2022-05-08"
},
{
"value": "",
"value_id": "",
"date": "2022-05-09"
},
{
"value": "",
"value_id": "",
"date": "2022-05-10"
},
{
"value": "",
"value_id": "",
"date": "2022-05-11"
}
]
Like in the object 2022-06-11 data is there, so the new array will consist an object which will have properties related to that object. Similar to if the object has start_date present which is also in date array, so the new array will consist object for those info. Otherwise it will create blank object respective to date.
But I am able to come with this
[
{
"value": "999",
"value_id": "aacc1765-a1d3-43c3-8233-beae19d258e5",
"date": "2022-05-06"
},
{
"value": "189",
"value_id": "ad95cc4a-ec72-4d6e-a452-f519358f265d",
"date": "2022-05-08"
},
{
"value": "",
"date": "2022-05-03"
},
{
"value": "",
"date": "2022-05-04"
},
{
"value": "",
"date": "2022-05-05"
},
{
"value": "",
"date": "2022-05-06"
},
{
"value": "",
"date": "2022-05-07"
},
{
"value": "",
"date": "2022-05-08"
},
{
"value": "",
"date": "2022-05-09"
},
{
"value": "",
"date": "2022-05-10"
},
{
"value": "",
"date": "2022-05-11"
},
{
"value": "",
"date": "2022-05-12"
},
{
"value": "",
"date": "2022-05-13"
},
{
"value": "",
"date": "2022-05-14"
},
{
"value": "",
"date": "2022-05-15"
},
{
"value": "",
"date": "2022-05-16"
},
{
"value": "",
"date": "2022-05-17"
},
{
"value": "",
"date": "2022-05-18"
},
{
"value": "",
"date": "2022-05-19"
},
{
"value": "",
"date": "2022-05-20"
},
{
"value": "",
"date": "2022-05-21"
},
{
"value": "",
"date": "2022-05-22"
},
{
"value": "",
"date": "2022-05-23"
},
{
"value": "",
"date": "2022-05-24"
},
{
"value": "",
"date": "2022-05-25"
},
{
"value": "",
"date": "2022-05-26"
},
{
"value": "",
"date": "2022-05-27"
},
{
"value": "",
"date": "2022-05-28"
},
{
"value": "",
"date": "2022-05-29"
},
{
"value": "",
"date": "2022-05-30"
}
]
It is taking only first entry and printing and rest are coming as blank.
My Code: -
var a = {};
dateArr = [];
for (var j = 0; j < this.date_val.length; j++) {
debugger;
var b = {}
console.log(val2.value[j]);
if (val2.value.length > 0) {
const newKey = this.date_val[j];
b[newKey] = val1.data;
// if (
// moment(val2.value[j].start_date).format("YYYY-MM-DD") !=
// this.date_val[j]
// ) {
// this.vala = val2.value[j].value;
// this.valb = val2.value[j].val_id;
// this.valc = moment(val2.value[j].start_date).format(
// "YYYY-MM-DD"
// );
// }
// if (
// moment(val2.value[j].start_date).format("YYYY-MM-DD") !=
// this.date_val[j]
// ) {
a = {
value:
val2.value[j] != undefined ? val2.value[j].value : "",
value_id:
val2.value[j] != undefined
? val2.value[j].v_id
: undefined,
date:
val2.value[j] != undefined
? moment(val2.value[j].start_date).format(
"YYYY-MM-DD"
)
: this.date_val[j],
};
// }
} else {
a = {
value: "",
value_id: undefined,
date: this.date_val[j],
};
}
dateArr.push(a);
}
this.nameArray.push({
key: val1.key,
key_val: val1.id,
date: dateArr,
});
Can someone please help me with this? Thanks in Advance.

var a = [
"2022-05-01",
"2022-05-02",
"2022-05-03",
"2022-05-04",
"2022-05-05",
"2022-05-06",
"2022-05-07",
"2022-05-08",
"2022-05-09",
"2022-05-10",
"2022-05-11",
"2022-05-12",
"2022-05-13",
"2022-05-14",
"2022-05-15",
"2022-05-16",
"2022-05-17",
"2022-05-18",
"2022-05-19",
"2022-05-20",
"2022-05-21",
"2022-05-22",
"2022-05-23",
"2022-05-24",
"2022-05-25",
"2022-05-26",
"2022-05-27",
"2022-05-28",
"2022-05-29",
"2022-05-30",
];
var b = [
{
k_id: "6dcb67eb-1c8a-4239-9446-f9d8f6a68086",
v_id: "aacc1765-a1d3-43c3-8233-beae19d258e5",
key: "Testing",
value: "999",
start_date: "2022-05-06T00:00:00.000Z",
end_date: "2022-05-06T00:00:00.000Z",
},
{
k_id: "6dcb67eb-1c8a-4239-9446-f9d8f6a68086",
v_id: "ad95cc4a-ec72-4d6e-a452-f519358f265d",
key: "Testing",
value: "189",
start_date: "2022-05-08T00:00:00.000Z",
end_date: "2022-05-08T00:00:00.000Z",
},
];
let results = a.map((dateString, idx) => {
// You'll want to parse the time, many ways
// to do this, then compare times. This is
// hardcoded to work for this exact format
let bWithMatchedIndices = b.find(
({ start_date }) => dateString === start_date.split("T")[0]
);
if (bWithMatchedIndices?.start_date.split("T")[0] === dateString) {
return {
date: dateString,
value: bWithMatchedIndices.value,
value_id: bWithMatchedIndices.v_id,
};
} else {
return {
date: dateString,
value: "",
value_id: "",
};
}
});
console.log(results);

Just loop over the dates in A and find a match in B. Then create an object with the members you need and push it to the resulting array.
interface NewItem {
date: string,
value: string,
value_id: string
}
function transform(a: any[], b: any[]): NewItem[] {
let newArray: NewItem[] = []
a.forEach(item => {
const objectFound = b.find(x => x.start_date.split('T')[0] === item)
if (objectFound) {
newArray.push({ date: item, value: objectFound.value, value_id: objectFound.v_id })
} else {
newArray.push({ date: item, value: '', value_id: '' })
}
})
return newArray
}
console.log(transform(a, b))
You might want to create interfaces for the two original objects too, but I think this should help you on your way just fine.
Here's the result in a Playground.

Related

Get keys from nested Javascript Object based on some condition

i am having JSON Object in the form of
{
"detailObject": {
"user": {
"userProperty": {
"active": {
"id": "3be0d467",
"value": null,
"duration": "4 hrs"
}
},
"userRegion": {
"active": {
"id": "3be0d467",
"value": null,
"duration": "5 hrs"
}
}
},
"OtherInfo": [
{
"year": {
"active": {
"id": "3be0d467",
"value": null,
"duration": ""
}
},
"volume": {
"active": {
"id": "3be0d467",
"value": null,
"duration": ""
}
}
}
]
}
}
Now i want to map it in a single object like {"userProperty":"4 hrs","userRegion":"5 hrs","year":"","volume":""} i.e parent key and duration
or [{"userProperty":"4 hrs"},{"userRegion":"5 hrs"},{"year":""},{"volume":""}]
You could do the exhausive traverse through the data object:
the base condition is to stop when a checked value is not an array and object
if the value to check is an array, continue to traverse through each element
if the value is an object, check if it contains the non-undefined path of active.duration, if the that condition is met, store the key and the value achieved from that path
const res = []
const exhausiveTraverse = (data) => {
if (isArray(data)) {
data.map((el) => exhausiveTraverse(el))
} else if (isObject(data)) {
Object.entries(data).map(([key, value]) => {
if (getByPath(value, ["active", "duration"]) !== undefined) {
res.push({ [key]: getByPath(value, ["active", "duration"]) })
} else {
exhausiveTraverse(value)
}
})
} else {
return undefined
}
}
Full code
const data = {
detailObject: {
user: {
userProperty: {
active: {
id: "3be0d467",
value: null,
duration: "4 hrs",
},
},
userRegion: {
active: {
id: "3be0d467",
value: null,
duration: "5 hrs",
},
},
},
OtherInfo: [
{
year: {
active: {
id: "3be0d467",
value: null,
duration: "",
},
},
volume: {
active: {
id: "3be0d467",
value: null,
duration: "",
},
},
},
],
},
}
const isArray = (arr) => Array.isArray(arr)
const isObject = (obj) =>
typeof obj === "object" && obj !== null && !Array.isArray(obj)
const getByPath = (obj, path) => {
try {
return path.reduce((acc, p) => acc[p], obj)
} catch (err) {
return undefined
}
}
const res = []
const exhausiveTraverse = (data) => {
if (isArray(data)) {
data.map((el) => exhausiveTraverse(el))
} else if (isObject(data)) {
Object.entries(data).map(([key, value]) => {
if (getByPath(value, ["active", "duration"]) !== undefined) {
res.push({ [key]: getByPath(value, ["active", "duration"]) })
} else {
exhausiveTraverse(value)
}
})
} else {
return undefined
}
}
exhausiveTraverse(data)
console.log(res)
You can do this by looping through the object's properties.
Note: This assumes that your object will always look the way you described it above, where:
detailObject.user is an object of sub-objects, where each sub-object has subObject.active.duration
detailObject.OtherInfo is an array of one object, where the object has object.active.duration
In this example, I use Object.entries().
const myObject = {
"detailObject": {
"user": {
"userProperty": {
"active": {
"id": "3be0d467",
"value": null,
"duration": "4 hrs"
}
},
"userRegion": {
"active": {
"id": "3be0d467",
"value": null,
"duration": "5 hrs"
}
}
},
"OtherInfo": [
{
"year": {
"active": {
"id": "3be0d467",
"value": null,
"duration": ""
}
},
"volume": {
"active": {
"id": "3be0d467",
"value": null,
"duration": ""
}
}
}
]
}
};
const results = {};
for (const [userDataName, userData] of Object.entries(myObject.detailObject.user)) {
results[userDataName] = userData.active.duration;
}
for (const [userDataName, userData] of Object.entries(myObject.detailObject.OtherInfo[0])) {
results[userDataName] = userData.active.duration;
}
console.log(JSON.stringify(results, null, '\t'));
Since the object has different types of data, they must be converted to the same type. I use flat to move the array at OtherInfo to a higher level. Then collect a new object using reduce.
const myObject = {
"detailObject": {
"user": {
"userProperty": {
"active": {
"id": "3be0d467",
"value": null,
"duration": "4 hrs"
}
},
"userRegion": {
"active": {
"id": "3be0d467",
"value": null,
"duration": "5 hrs"
}
}
},
"OtherInfo": [{
"year": {
"active": {
"id": "3be0d467",
"value": null,
"duration": ""
}
},
"volume": {
"active": {
"id": "3be0d467",
"value": null,
"duration": ""
}
}
}]
}
};
const result = Object.values(myObject.detailObject)
.flat(Infinity)
.reduce((obj, value) => (Object.entries(value).forEach(item => obj[item[0]] = item[1].active.duration), obj), {});
console.log(result);
Recursive approach will be helpful here. Use Object.entries and recursively check for "active" and "duration" keys.
const recuriveAdd = (obj, res) => {
if (Array.isArray(obj)) {
obj.forEach((item) => recuriveAdd(item, res));
} else {
Object.entries(obj).forEach(([key, value]) => {
if ("active" in value) {
res.push({ [key]: value.active.duration });
} else {
Object.values(value).forEach((item) => recuriveAdd(item, res));
}
});
}
};
obj = {
detailObject: {
user: {
userProperty: {
active: {
id: "3be0d467",
value: null,
duration: "4 hrs",
},
},
userRegion: {
active: {
id: "3be0d467",
value: null,
duration: "5 hrs",
},
},
},
OtherInfo: [
{
year: {
active: {
id: "3be0d467",
value: null,
duration: "",
},
},
volume: {
active: {
id: "3be0d467",
value: null,
duration: "",
},
},
},
],
},
};
const res = [];
recuriveAdd(obj, res);
console.log(res);
Try this out.
const jsonObj = {
"detailObject": {
"user": {
"userProperty": {
"active": {
"id": "3be0d467",
"value": null,
"duration": "4 hrs"
}
},
"userRegion": {
"active": {
"id": "3be0d467",
"value": null,
"duration": "5 hrs"
}
}
},
"OtherInfo": [{
"year": {
"active": {
"id": "3be0d467",
"value": null,
"duration": ""
}
},
"volume": {
"active": {
"id": "3be0d467",
"value": null,
"duration": ""
}
}
}]
}
};
const {detailObject: {user}} = jsonObj;
const {detailObject: {OtherInfo: [other]}} = jsonObj;
const customObj = {...user, ...other};
const myObj = (
({
userProperty: {active: {duration: propDur}},
userRegion: {active: {duration: regDur}},
year: {active: {duration: yearDur}},
volume: {active: {duration: volDur}}
}) => ({
userProperty: propDur,
userRegion: regDur,
year: yearDur,
volume: volDur
})
)(customObj);
console.log(myObj);
I think the best solution should be using destructuring of objects. I created myObj, the one that you need, using IIFE.
Using my approach you can also declare a default value for a key, if not found in the jsonObj.

Flatten an object using lodash

I have below this nested object
I need to create an array using this object containing keys. And if keys are object then it should use .dot syntax. and if it is an array then it should give me key.0.keyName. Is it possible to do so?
Output
[
"AllowIPNPayment",
"AllowOnlinePayment",
"MetaData.CreateTime",
"MetaData.LastUpdatedTime",
"CustomField.0.DefinitionId",
"CustomField.0.Name",
"CustomField.0.Type",
...
]
What I have tried is just ugly and does give me expected result. If it is possible with more concise way.
const invoiceObject = { "AllowIPNPayment": false, "AllowOnlinePayment": false, "AllowOnlineCreditCardPayment": false, "AllowOnlineACHPayment": false, "domain": "QBO", "sparse": false, "Id": "16", "SyncToken": "1", "MetaData": { "CreateTime": "2020-03-25T15:10:40-07:00", "LastUpdatedTime": "2020-03-26T11:06:49-07:00" }, "CustomField": [{ "DefinitionId": "1", "Name": "Crew #", "Type": "StringType" }], "DocNumber": "1007", "TxnDate": "2020-03-03", "CurrencyRef": { "value": "USD", "name": "United States Dollar" }, "LinkedTxn": [{ "TxnId": "32", "TxnType": "Payment" }], "Line": [{ "Id": "1", "LineNum": 1, "Description": "Custom Design", "Amount": 750, "DetailType": "SalesItemLineDetail", "SalesItemLineDetail": { "ItemRef": { "value": "4", "name": "Design" }, "UnitPrice": 75, "Qty": 10, "TaxCodeRef": { "value": "NON" } } }, { "Amount": 750, "DetailType": "SubTotalLineDetail", "SubTotalLineDetail": {} } ], "TxnTaxDetail": { "TotalTax": 0 }, "CustomerRef": { "value": "13", "name": "uiool" }, "CustomerMemo": { "value": "Thank you for your business and have a great day!" }, "SalesTermRef": { "value": "3" }, "DueDate": "2020-04-02", "TotalAmt": 750, "ApplyTaxAfterDiscount": false, "PrintStatus": "NeedToPrint", "EmailStatus": "NotSet", "BillEmail": { "Address": "uiikoool" }, "Balance": 450 }
let object = {}
for (let k in invoiceObject) {
if (typeof invoiceObject[k] === "object") {
object[k] = {};
for (let l in invoiceObject[k]) {
object[k][l] = "";
}
} else if (typeof invoiceObject[k] === "array") {
object[k] = [];
for (let l in invoiceObject[k][0]) {
object[k][l] = "";
}
} else {
object[k] = "";
}
}
console.log(object)
You can create a recursive function (getSchema) that checks if a value (val) is an object (arrays included), iterate it with _.flatMap(), and collects the keys until it hits a value which is not an object. It then joins the collected keys and returns the string.
const getSchema = (val, keys = []) =>
_.isObject(val) ? // if it's an object or array
_.flatMap(val, (v, k) => getSchema(v, [...keys, k])) // iterate it and call fn with the value and the collected keys
:
keys.join('.') // return the joined keys
const invoiceObject = { "AllowIPNPayment": false, "AllowOnlinePayment": false, "AllowOnlineCreditCardPayment": false, "AllowOnlineACHPayment": false, "domain": "QBO", "sparse": false, "Id": "16", "SyncToken": "1", "MetaData": { "CreateTime": "2020-03-25T15:10:40-07:00", "LastUpdatedTime": "2020-03-26T11:06:49-07:00" }, "CustomField": [{ "DefinitionId": "1", "Name": "Crew #", "Type": "StringType" }], "DocNumber": "1007", "TxnDate": "2020-03-03", "CurrencyRef": { "value": "USD", "name": "United States Dollar" }, "LinkedTxn": [{ "TxnId": "32", "TxnType": "Payment" }], "Line": [{ "Id": "1", "LineNum": 1, "Description": "Custom Design", "Amount": 750, "DetailType": "SalesItemLineDetail", "SalesItemLineDetail": { "ItemRef": { "value": "4", "name": "Design" }, "UnitPrice": 75, "Qty": 10, "TaxCodeRef": { "value": "NON" } } }, { "Amount": 750, "DetailType": "SubTotalLineDetail", "SubTotalLineDetail": {} } ], "TxnTaxDetail": { "TotalTax": 0 }, "CustomerRef": { "value": "13", "name": "uiool" }, "CustomerMemo": { "value": "Thank you for your business and have a great day!" }, "SalesTermRef": { "value": "3" }, "DueDate": "2020-04-02", "TotalAmt": 750, "ApplyTaxAfterDiscount": false, "PrintStatus": "NeedToPrint", "EmailStatus": "NotSet", "BillEmail": { "Address": "uiikoool" }, "Balance": 450 }
const result = getSchema(invoiceObject)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
Without lodash, the main change is to use Object.entries() to get an array of [key, value] pairs, since Array.flatMap() can't iterate objects:
const getSchema = (val, keys = []) =>
typeof val === 'object' && val !== null ? // if it's an object or array
Object.entries(val) // get [key, value] pairs of object/array
.flatMap(([k, v]) => getSchema(v, [...keys, k])) // iterate it and call fn with the value and the collected keys
:
keys.join('.') // return the joined keys
const invoiceObject = { "AllowIPNPayment": false, "AllowOnlinePayment": false, "AllowOnlineCreditCardPayment": false, "AllowOnlineACHPayment": false, "domain": "QBO", "sparse": false, "Id": "16", "SyncToken": "1", "MetaData": { "CreateTime": "2020-03-25T15:10:40-07:00", "LastUpdatedTime": "2020-03-26T11:06:49-07:00" }, "CustomField": [{ "DefinitionId": "1", "Name": "Crew #", "Type": "StringType" }], "DocNumber": "1007", "TxnDate": "2020-03-03", "CurrencyRef": { "value": "USD", "name": "United States Dollar" }, "LinkedTxn": [{ "TxnId": "32", "TxnType": "Payment" }], "Line": [{ "Id": "1", "LineNum": 1, "Description": "Custom Design", "Amount": 750, "DetailType": "SalesItemLineDetail", "SalesItemLineDetail": { "ItemRef": { "value": "4", "name": "Design" }, "UnitPrice": 75, "Qty": 10, "TaxCodeRef": { "value": "NON" } } }, { "Amount": 750, "DetailType": "SubTotalLineDetail", "SubTotalLineDetail": {} } ], "TxnTaxDetail": { "TotalTax": 0 }, "CustomerRef": { "value": "13", "name": "uiool" }, "CustomerMemo": { "value": "Thank you for your business and have a great day!" }, "SalesTermRef": { "value": "3" }, "DueDate": "2020-04-02", "TotalAmt": 750, "ApplyTaxAfterDiscount": false, "PrintStatus": "NeedToPrint", "EmailStatus": "NotSet", "BillEmail": { "Address": "uiikoool" }, "Balance": 450 }
const result = getSchema(invoiceObject)
console.log(result)
inspired by the answer given in this post and understanding you just want to get the property-names, not values, you could do it like this. sorry, this uses plain javascript.
function flattenObjectToKeyArray(ob) {
var toReturn = [];
for (var prop in ob) {
if (!ob.hasOwnProperty(prop)) continue;
if ((typeof ob[prop]) == 'object' && ob[prop] !== null) {
var flatObject = flattenObjectToKeyArray(ob[prop]);
for (var idx = 0; idx < flatObject.length; idx++) {
toReturn.push(prop + '.' + flatObject[idx]);
}
} else {
toReturn.push(prop);
}
}
return toReturn;
}
You could solve this with a recursive function. The function below keeps track of the current keys, and joins them as soon as an end point is reached (a non-object or empty object/array).
const invoiceObject = { "AllowIPNPayment": false, "AllowOnlinePayment": false, "AllowOnlineCreditCardPayment": false, "AllowOnlineACHPayment": false, "domain": "QBO", "sparse": false, "Id": "16", "SyncToken": "1", "MetaData": { "CreateTime": "2020-03-25T15:10:40-07:00", "LastUpdatedTime": "2020-03-26T11:06:49-07:00" }, "CustomField": [{ "DefinitionId": "1", "Name": "Crew #", "Type": "StringType" }], "DocNumber": "1007", "TxnDate": "2020-03-03", "CurrencyRef": { "value": "USD", "name": "United States Dollar" }, "LinkedTxn": [{ "TxnId": "32", "TxnType": "Payment" }], "Line": [{ "Id": "1", "LineNum": 1, "Description": "Custom Design", "Amount": 750, "DetailType": "SalesItemLineDetail", "SalesItemLineDetail": { "ItemRef": { "value": "4", "name": "Design" }, "UnitPrice": 75, "Qty": 10, "TaxCodeRef": { "value": "NON" } } }, { "Amount": 750, "DetailType": "SubTotalLineDetail", "SubTotalLineDetail": {} } ], "TxnTaxDetail": { "TotalTax": 0 }, "CustomerRef": { "value": "13", "name": "uiool" }, "CustomerMemo": { "value": "Thank you for your business and have a great day!" }, "SalesTermRef": { "value": "3" }, "DueDate": "2020-04-02", "TotalAmt": 750, "ApplyTaxAfterDiscount": false, "PrintStatus": "NeedToPrint", "EmailStatus": "NotSet", "BillEmail": { "Address": "uiikoool" }, "Balance": 450 };
function getDotKeys(item, keys = []) {
const isObject = item && typeof item == "object";
if (!isObject) return Array.of(keys.join("."));
const pairs = Array.isArray(item)
? item.map((value, index) => [index, value])
: Object.entries(item);
const isEmpty = !pairs.length;
if (isEmpty) return Array.of(keys.join("."));
const result = [];
for (const [key, value] of pairs) {
const dotKeys = getDotKeys(value, [...keys, key]);
result.push(...dotKeys);
}
return result;
}
console.log(getDotKeys(invoiceObject));
This does produce a different result than what you have in your question, since your solution stops at the second level for objects and third level for arrays. This solution also includes more then only index 0.

filter array of objects by object value

Trying to filter an array of objects by start and end object values.
start = "Feb-2015"
end = "Jul-2015"
result = array.sort(2,7);
have tried this but I have dates, I will be not knowing the index of it.
array = [
{
"date": "Jan-2015"
},
{
"date": "Feb-2015"
},
{
"date": "Mar-2015"
},
{
"date": "Apr-2015"
},
{ "date": "May-2015"
},
{,
"date": "Jun-2015"
},
{ "date": "Jul-2015"
},
{
"date": "Aug-2015"
}
]
expected output:-
result = [
{
"date": "Feb-2015"
},
{
"date": "Mar-2015"
},
{
"date": "Apr-2015"
},
{ "date": "May-2015"
},
{,
"date": "Jun-2015"
},
{
"date": "Jul-2015"
}
]
const data = [{"date":"Jan-2018"},{"date":"Feb-2015"},{"date":"Mar-2015"},{"date":"Apr-2015"},{"date":"May-2015"},{"date":"Jun-2015"},{"date":"Jul-2015"},{"date":"Aug-2015"}];
console.log(data.sort((a, b) => { return new Date(a.date) - new Date(b.date)}));
Use below.
array = [{
"date": "Jan-2015"
},
{
"date": "Aug-2015"
},
{
"date": "Feb-2015"
},
{
"date": "Mar-2015"
},
{
"date": "Apr-2015"
},
{
"date": "May-2015"
},
{
"date": "Jun-2015"
},
{
"date": "Jul-2015"
}
];
//filter
sort = (arr, start, end) => {
let arrayFiltered = arr.filter((obj) => {
obj.dateObj = new Date(obj.date.substring(0, 3) + obj.date.substring(4, 8));
return (obj.dateObj.getMonth() + 1) >= start && (obj.dateObj.getMonth() + 1) <= end;
});
console.log(arrayFiltered.sort(obj => obj.dateObj));
};
sort(array, 2, 7);
Output
[{
"date": "Feb-2015",
"dateObj": "2015-01-31T18:30:00.000Z"
}, {
"date": "Mar-2015",
"dateObj": "2015-02-28T18:30:00.000Z"
}, {
"date": "Apr-2015",
"dateObj": "2015-03-31T18:30:00.000Z"
}, {
"date": "May-2015",
"dateObj": "2015-04-30T18:30:00.000Z"
}, {
"date": "Jun-2015",
"dateObj": "2015-05-31T18:30:00.000Z"
}, {
"date": "Jul-2015",
"dateObj": "2015-06-30T18:30:00.000Z"
}]

Re-arrage JSON values from existing values

The JSON provided is kind of unstructured and doesn't meet many of my
requirements. I have tried this many ways but does take a very long time
when I provide 100,000 records
Implemented Code
for (var f in stack.data) {
var field = new Object();
for (var o in stack.data[f]['field_values']) {
field[stack.data[f]['field_values'][o]['field_name']] = stack.data[f]['field_values'][o]['value'];
}
stack.data[f]['field_values'] = field;
}
console.log(JSON.stringify(stack, null, 2));
Input JSON:
var stack = {
"data": [{
"id": 950888888073,
"name": "www.stackoverflow.com",
"field_values": [{
"field_name": "Newsletter?",
"value": true
},
{
"field_name": "Parent",
"value": 950888661
},
{
"field_name": "Birthday",
"value": "2018-04-29"
},
{
"field_name": "Related matter",
"value": 1055396205
},
{
"field_name": "Referral",
"value": "Don Ho"
},
{
"field_name": "Spouse",
"value": "Wo Fat"
}
]
}]
}
Expected Output:
{
"data": [
{
"id": 950888888073,
"name": "www.stackoverflow.com",
"field_values": {
"Newsletter?": true,
"Parent": "Gigi Hallow",
"Birthday": "2018-04-29",
"Related": "2012-00121-Sass",
"Referral": "Don Ho",
"Spouse": "Wo Fat"
}
Sometimes "field_values can be empty. Need to check them as well
{
"id": 950821118875,
"name": "www.google.com",
"field_values": [],
}
This is mostly re-arranging the values. Here values becomes keys. There should actually be one liner to handle this, but i am run out of options.
Hope the question is clear
It would probably help to declare a variable to hold the array element, rather than doing 4 levels of indexing every time through the loop. You can also use destructuring to extract the properties of the object.
And use {} rather than new Object.
Even if this doesn't improve performance, it makes the code easier to read.
var stack = {
"data": [{
"id": 950888888073,
"name": "www.stackoverflow.com",
"field_values": [{
"field_name": "Newsletter?",
"value": true
},
{
"field_name": "Parent",
"value": 950888661
},
{
"field_name": "Birthday",
"value": "2018-04-29"
},
{
"field_name": "Related matter",
"value": 1055396205
},
{
"field_name": "Referral",
"value": "Don Ho"
},
{
"field_name": "Spouse",
"value": "Wo Fat"
}
]
}]
}
for (var f in stack.data) {
const field = {};
const fobj = stack.data[f];
for (var o in fobj.field_values) {
const {field_name, value} = fobj.field_values[o];
field[field_name] = value;
}
fobj.field_values = field;
}
console.log(JSON.stringify(stack, null, 2));

How to make subarrays containing a same string from an array?

I have an array like this :
[
{
"title": "name",
"value": ""
},
{
"title": "version",
"value": ""
},
{
"title": "inventory_name",
"value": ""
},
{
"title": "inventory_version",
"value": ""
},
{
"title": "differed",
"value": ""
},
{
"title": "differed_name",
"value": ""
},
{
"title": "accept_error_while_reboot",
"value": ""
},
{
"title": "setup_check",
"value": ""
},
{
"title": "setup_install",
"value": ""
},
{
"title": "setup_install_partial",
"value": ""
},
{
"title": "params_install",
"value": ""
},
{
"title": "params_install_partial",
"value": ""
},
{
"title": "results_install_ok",
"value": ""
},
{
"title": "results_install_reboot_defered",
"value": ""
},
{
"title": "results_install_reboot_immediate",
"value": ""
},
{
"title": "results_install_partial_ok",
"value": ""
},
{
"title": "results_install_partial_reboot_defered",
"value": ""
},
{
"title": "results_install_partial_reboot_immediate",
"value": ""
}
];
Is it possible to make subarrays that contains the same title field string ?
For example in this case , I will have :
array1 = [
{
"title": "differed",
"value": ""
},
{
"title": "differed_name",
"value": ""
}
]
array2 = [
{
"title": "setup_check",
"value": ""
},
{
"title": "setup_install",
"value": ""
},
{
"title": "setup_install_partial",
"value": ""
}
]
and so on...
In case of single elements , I should have :
[
{
"title": "name",
"value": ""
}
]
I'm searching for a generic approach.
I know I can use, for example, indexOf('results') with filter function, however I'd like if it's possible to avoid the hardcode since it's not always the same titles.
Any ideas ?
Fiddle
You can use an object to group similar items:
var groups = {};
parameter_list.forEach(function(p){
var key = p.title.split('_')[0];
if(!groups[key]) {
groups[key] = [];
}
groups[key].push(p);
});
Working demo:
http://jsfiddle.net/t459o6v1/3/
Group the data with .reduce()
var groups = data.reduce(function(result, currentValue) {
var key = currentValue.title.split("_")[0];
if (typeof result[key] === "undefined") {
result[key] = [];
}
result[key].push(currentValue);
return result;
}, {});
And then (if needed) use .map() to transform the object into "subarrays"
var subArrays = Object.keys(groups).map(function(key) {
return groups[key];
});
var data = [{
"title": "name",
"value": ""
}, {
"title": "version",
"value": ""
}, {
"title": "inventory_name",
"value": ""
}, {
"title": "inventory_version",
"value": ""
}, {
"title": "differed",
"value": ""
}, {
"title": "differed_name",
"value": ""
}, {
"title": "accept_error_while_reboot",
"value": ""
}, {
"title": "setup_check",
"value": ""
}, {
"title": "setup_install",
"value": ""
}, {
"title": "setup_install_partial",
"value": ""
}, {
"title": "params_install",
"value": ""
}, {
"title": "params_install_partial",
"value": ""
}, {
"title": "results_install_ok",
"value": ""
}, {
"title": "results_install_reboot_defered",
"value": ""
}, {
"title": "results_install_reboot_immediate",
"value": ""
}, {
"title": "results_install_partial_ok",
"value": ""
}, {
"title": "results_install_partial_reboot_defered",
"value": ""
}, {
"title": "results_install_partial_reboot_immediate",
"value": ""
}];
var groups = data.reduce(function(result, currentValue) {
var key = currentValue.title.split("_")[0];
if (typeof result[key] === "undefined") {
result[key] = [];
}
result[key].push(currentValue);
return result;
}, {});
var subArrays = Object.keys(groups).map(function(key) {
return groups[key];
});
console.log(JSON.stringify(subArrays));
I came up with a solution using Immutable.JS, but you could probably do something similar with lodash or underscore. Note that this is a functional version, not imperative.
First create a function that gets the prefix:
function getPrefix(name) {
var substr = name.substring(0, name.indexOf('_'))
return substr ? substr : name;
}
Then use the groupBy function:
Immutable.fromJS(arr).groupBy(element => getPrefix( element['title']))
.toJS();
This will give you an array of arrays with the title as it's key.

Categories

Resources