remove elements from nested object array - javascript

I want to remove object based on conditional check from the JSON object using angularjs/jQuery.
I tried with below code but output is not as expected.
Demo: https://plnkr.co/edit/EWwbETITqn7G79Xypt0g?p=preview
angular.module('ui.bootstrap.demo').controller('DataCtrl', function ($scope) {
$scope.responseData = {
"data": [{
"name": "Machine", "quantity": 20, "snVal": 22,
"machine1": [{ "id": 2009, "machineName": "ASD1", "trackID": "34219", "status": "delivered" },
{ "id": 27893, "machineName": "PX20AA", "trackID": "3422", "status": "avail" }],
"machine2": [{ "id": 1023, "machineName": "XY22", "trackID": "1345", "status": "avail" },
{ "id": 1233, "machineName": "PP3DF", "trackID": "112", "status": "delivered" }
]
}]
}
console.log("R1 :: " + JSON.stringify($scope.responseData));
$scope.newResponse = $.grep($scope.responseData.data, function (element, index) { return element.status == "delivered" }, true);
console.log("R2 after removing elements:: " + JSON.stringify($scope.newResponse));
});

Try this,
let responseData = { "data": [{ "name": "Machine", "quantity": 20, "snVal": 22, "machine1": [{ "id": 2009, "machineName": "ASD1", "trackID": "34219", "status": "delivered" }, { "id": 27893, "machineName": "PX20AA", "trackID": "3422", "status": "avail" }], "machine2": [{ "id": 1023, "machineName": "XY22", "trackID": "1345", "status": "avail" }, { "id": 1233, "machineName": "PP3DF", "trackID": "112", "status": "delivered" }] }] } ;
let newResponse = responseData;
newResponse.data.forEach(function (item) {
for (j in item) {
if (j.includes("machine")) {
//better you check if type is array, using Object.prototype.toString.call(j) === "[object Array]"
item[j] = item[j].reduce(function (acc, machine) {
if (machine.status !== "delivered"){
acc.push(machine);
}
return acc;
}, []);
}
}
})|
console.log(newResponse);
Here we are just iterating through all objects in the data field. Since properties like machine1, machine2 is an array, we iterate through it and filter all machines which are not delivered.
You must note that I have used a for-in loop and array reduce() method here.

Related

How to get an array of object values embedded within an array of objects

I have an array that has objects, within which is an array of objects as shown below.
const property = [
{
houses: {
"id": "HT-00001",
"features": [{ "id": "FT-0001", "name": "balcony"}, { "id": "FT-0002", "name": "wifi"}],
"opts": [{
"desc": "House description",
"bed": 3,
"bath": 1,
"location": "Location of property",
"name": "Name of Property Listing",
"isDefault": false,
"listPrice": [{"amount": 123, "currency": "EUR"}]
}]
},
currency: {
"currency": "EUR"
}
},
{
houses: {
"id": "HT-00002",
"features": [{ "id": "FT-0003", "name": "tiled floor"}, { "id": "FT-0002", "name": "wifi"}],
"opts": [{
"desc": "House description",
"bed": 3,
"bath": 1,
"location": "Location of property",
"name": "Name of Property Listing",
"isDefault": false,
"listPrice": [{"amount": 123, "currency": "EUR"}]
}]
},
currency: {
"currency": "EUR"
}
},
{
houses: {
"id": "HT-00003",
"features": [{ "id": "FT-0004", "name": "refrigerator"}, { "id": "FT-0005", "name": "microwave"}],
"opts": [{
"desc": "House description",
"bed": 3,
"bath": 1,
"location": "Location of property",
"name": "Name of Property Listing",
"isDefault": false,
"listPrice": [{"amount": 123, "currency": "EUR"}]
}]
},
currency: {
"currency": "EUR"
}
},
];
Now, I am getting a challenge extracting a unique list of features name as an array. Take note that the features has objects and it is within houses object which is an object of object of the array that I am dealing with. What I want is just an array of all unique feature names that are within the provided property array. This is what I have tried, even though it is so much confusing and I need your help.
const allFeatures = property?.map((propertyItem) => {
let features = Array.from(new Set(propertyItem?.houses?.features?.map(({ name }) => name)));
return features;
});
The expected array will be something like:
allFeatures = ['balcony', 'wifi', 'tiled floor', 'refrigerator', 'microwave']
Iterate over each "house" object and, further, iterate over each features array within each object. You can use map for that inner iteration, but to get a resulting flattened array use flatMap for the outer iteration. You can then create a set from that, and then get the depuped array from that set.
(Note: in my experience if you put your code all on one line it makes it more difficult to debug.)
const property=[{houses:{id:"HT-00001",features:[{id:"FT-0001",name:"balcony"},{id:"FT-0002",name:"wifi"}],opts:[{desc:"House description",bed:3,bath:1,location:"Location of property",name:"Name of Property Listing",isDefault:!1,listPrice:[{amount:123,currency:"EUR"}]}]},currency:{currency:"EUR"}},{houses:{id:"HT-00002",features:[{id:"FT-0003",name:"tiled floor"},{id:"FT-0002",name:"wifi"}],opts:[{desc:"House description",bed:3,bath:1,location:"Location of property",name:"Name of Property Listing",isDefault:!1,listPrice:[{amount:123,currency:"EUR"}]}]},currency:{currency:"EUR"}},{houses:{id:"HT-00003",features:[{id:"FT-0004",name:"refrigerator"},{id:"FT-0005",name:"microwave"}],opts:[{desc:"House description",bed:3,bath:1,location:"Location of property",name:"Name of Property Listing",isDefault:!1,listPrice:[{amount:123,currency:"EUR"}]}]},currency:{currency:"EUR"}}];
const allFeatures = property.flatMap(obj => {
return obj.houses.features.map(feature => {
return feature.name;
});
});
const deduped = [...new Set(allFeatures)];
console.log(deduped);
As #andy has indicated Array#flatMap, Array#map and [...new Set(features)] is the way to go. Here, I'm using arrow functions and Object destructuring as well.
const property = [ { houses: { "id": "HT-00001", "features": [{ "id": "FT-0001", "name": "balcony"}, { "id": "FT-0002", "name": "wifi"}], "opts": [{ "desc": "House description", "bed": 3, "bath": 1, "location": "Location of property", "name": "Name of Property Listing", "isDefault": false, "listPrice": [{"amount": 123, "currency": "EUR"}] }] }, currency: { "currency": "EUR" } }, { houses: { "id": "HT-00002", "features": [{ "id": "FT-0003", "name": "tiled floor"}, { "id": "FT-0002", "name": "wifi"}], "opts": [{ "desc": "House description", "bed": 3, "bath": 1, "location": "Location of property", "name": "Name of Property Listing", "isDefault": false, "listPrice": [{"amount": 123, "currency": "EUR"}] }] }, currency: { "currency": "EUR" } }, { houses: { "id": "HT-00003", "features": [{ "id": "FT-0004", "name": "refrigerator"}, { "id": "FT-0005", "name": "microwave"}], "opts": [{ "desc": "House description", "bed": 3, "bath": 1, "location": "Location of property", "name": "Name of Property Listing", "isDefault": false, "listPrice": [{"amount": 123, "currency": "EUR"}] }] }, currency: { "currency": "EUR" } } ],
features = [...new Set(
property.flatMap(
({houses:{features}}) => features.map(({name}) => name)
)
)];
console.log( features );

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.

Objects keys value to be updated with arrays value

Below is my Attempt, I have an object which has array of objects within it, it has a field: 'positionTitle'.
I also have an array of objects which also has a 'positionTitle'
They both have similar data I want all of the values for the positionTitles in my 'individualsData' to go into 'graphData' and be able to now use this new graphData!
I think my attempt is wrong its treating them both as arrays?
Thanks, Dale
graphData = {
"engagementAreas": [{
"id": "1",
"engagementTypes": [{
"name": "forestry",
"engagements": []
},
{
"name": "houses",
"engagements": [{
"name": "engagement1",
"members": [{
"position": {
"id": "3434",
"positionTitle": "Manager"
}
}]
}]
}
]
}]
}, {
"name": "landscaping",
"engagements": [{
"name": "engagement1343",
"members": [{
"position": {
"id": "4545",
"positionTitle": "Senior Manager"
}
}]
}]
}
IndividualData = [{
"account": {
"id": "001b000003WnPy1AAF",
"fullName": "Adnan A. Khan"
},
"positions": [{
"id": "a16b0000004AxeBAAS",
"organizationId": "001b0000005gxmlAAA",
"organizationName": "a",
"positionTitle": "Senior Manager, Energy",
"positionLevel": "5-Middle Management & Advisers",
"isPrimary": true,
"startDate": "2016-10-07",
"endDate": null
}]
}, {
"account": {
"id": "0010X000048DDMsQAO",
"fullName": "Christine Leong"
},
"positions": [{
"id": "a160X000004nKfhQAE",
"organizationId": "001b0000005gxmlAAA",
"organizationName": "a",
"positionTitle": "Managing Director",
"positionLevel": "4-Head of Business Unit/Head of Region",
"isPrimary": true,
"startDate": "2018-03-05",
"endDate": null
}]
}
What I expect to see:
NEWgraphData = {
"engagementAreas": [{
"id": "1",
"engagementTypes": [{
"name": "forestry",
"engagements": []
},
{
"name": "houses",
"engagements": [{
"name": "engagement1",
"members": [{
"position": {
"id": "3434",
"positionTitle": "Senior Manager, Energy" <== from individualsdata
}
}]
}]
}
]
}]
}, {
"name": "landscaping",
"engagements": [{
"name": "engagement1343",
"members": [{
"position": {
"id": "4545",
"positionTitle": "Managing Director" <== also from individuals data
}
}]
}]
}
graphData.engagementAreas.map((el, i) => {
el.engagementTypes.engagements.members.position.positionTitle = individualsData.positions.positionTitle;
return el;
})
As engagementTypes, engagements and members properties are also array of objects, you have to loop them as well as below.
graphData.engagementAreas.map((el, i) => {
el.engagementTypes.forEach((et) => {
et.engagements.forEach((eg) => {
eg.members.forEach((mem) => {
mem.position.positionTitle = individualsData.positions.positionTitle; // make sure this is correct
});
});
});
return el;
})
Here is the solution. but you have to choose what individual data item will be the pick for the positionTitle
graphData.engagementAreas.map((el, i) => {
return el.engagementTypes.map((el2,i2) => {
return el2.engagements.map( (el3,i3) => {
return el3.members.map((el4,i4) => {
return el4.position.positionTitle =individualsDt[0].positions.[0].positionTitle;// take a look here, i just pick positionTitle staticly
})
})
})
});
see implementation in console here enter link description here

How to get the respective JSON object based on id

how to get the respective nested JSON object based on Id. For example below is my complete JSON.
[
{
"id": 1,
"title": "ASD Headquarters",
"items": [
{
"id": 11,
"title": "San Jose",
"items": [
{
"id": 13,
"title": "Jensen Chapman's Team",
"items": [
{
"id": 14,
"title": "Jimmy John"
},
{
"id": 15,
"title": "Daniel Mills"
},
{
"id": 16,
"title": "Chris Boden"
}
]
}
]
},
{
"id": 12,
"title": "Irvine",
"items": [
{
"id": 23,
"title": "Tracey Chapman's Team",
"items": [
{
"id": 24,
"title": "San Jesus"
},
{
"id": 25,
"title": "Fat Albert"
},
{
"id": 26,
"title": "Connor McDavid"
}
]
}
]
},
{
"id": 30,
"title": "San Diego",
"items": [
{
"id": 31,
"title": "Duran Duran's Team",
"items": [
{
"id": 32,
"title": "Amberlynn Pinkerton"
},
{
"id": 33,
"title": "Tony Mejia"
},
{
"id": 34,
"title": "Richard Partridge"
},
{
"id": 35,
"title": "Elliot Stabler"
}
]
},
{
"id": 40,
"title": "Steely Dan's Team",
"items": [
{
"id": 36,
"title": "Tony Stark"
},
{
"id": 37,
"title": "Totally Rad"
},
{
"id": 38,
"title": "Matt Murdock"
},
{
"id": 39,
"title": "Stan Lee"
}
]
}
]
}
]
}
]
From the above json how do i filter only particular nested object which have id as 11 => {"id": 11} using underscore.js
Output which i required is : {
"id":11,
"title":"San Jose",
"items":[
{
"id":13,
"title":"Jensen Chapman's Team",
"items":[
{
"id":14,
"title":"Jimmy John"
},
{
"id":15,
"title":"Daniel Mills"
},
{
"id":16,
"title":"Chris Boden"
}
]
}
]
}
You can use a recursive algorithm to look for an object in the current array as well as the nested ones.
var data = [{"id":1,"title":"ASD Headquarters","items":[{"id":11,"title":"San Jose","items":[{"id":13,"title":"Jensen Chapman's Team","items":[{"id":14,"title":"Jimmy John"},{"id":15,"title":"Daniel Mills"},{"id":16,"title":"Chris Boden"}]}]},{"id":12,"title":"Irvine","items":[{"id":23,"title":"Tracey Chapman's Team","items":[{"id":24,"title":"San Jesus"},{"id":25,"title":"Fat Albert"},{"id":26,"title":"Connor McDavid"}]}]},{"id":30,"title":"San Diego","items":[{"id":31,"title":"Duran Duran's Team","items":[{"id":32,"title":"Amberlynn Pinkerton"},{"id":33,"title":"Tony Mejia"},{"id":34,"title":"Richard Partridge"},{"id":35,"title":"Elliot Stabler"}]},{"id":40,"title":"Steely Dan's Team","items":[{"id":36,"title":"Tony Stark"},{"id":37,"title":"Totally Rad"},{"id":38,"title":"Matt Murdock"},{"id":39,"title":"Stan Lee"}]}]}]}];
console.log(find(12, data));
function find(id, [head, ...tail]) {
if (!head)
return null;
return checkObj(id, head) || find(id, tail);
}
function checkObj(id, obj) {
return obj.id === id ? obj : find(id, obj.items || [])
}
This also uses parameter destructuring in order to conveniently separate the "head" of the array from its "tail".
It could also be done within a single function.
var data = [{"id":1,"title":"ASD Headquarters","items":[{"id":11,"title":"San Jose","items":[{"id":13,"title":"Jensen Chapman's Team","items":[{"id":14,"title":"Jimmy John"},{"id":15,"title":"Daniel Mills"},{"id":16,"title":"Chris Boden"}]}]},{"id":12,"title":"Irvine","items":[{"id":23,"title":"Tracey Chapman's Team","items":[{"id":24,"title":"San Jesus"},{"id":25,"title":"Fat Albert"},{"id":26,"title":"Connor McDavid"}]}]},{"id":30,"title":"San Diego","items":[{"id":31,"title":"Duran Duran's Team","items":[{"id":32,"title":"Amberlynn Pinkerton"},{"id":33,"title":"Tony Mejia"},{"id":34,"title":"Richard Partridge"},{"id":35,"title":"Elliot Stabler"}]},{"id":40,"title":"Steely Dan's Team","items":[{"id":36,"title":"Tony Stark"},{"id":37,"title":"Totally Rad"},{"id":38,"title":"Matt Murdock"},{"id":39,"title":"Stan Lee"}]}]}]}];
console.log(find(12, data));
function find(id, [head, ...tail]) {
if (!head)
return null;
if (head.id === id)
return head;
return find(id, head.items || []) || find(id, tail);
}

Fuzzy search deep array only on certain properties

I have a JSON dataset which could be very large when it returns, with the following structure for each object:
{
"ctr": 57,
"averageECPC": 23,
"cost": 2732.54,
"margin": 66,
"profit": 2495.9,
"property": {
"value": "Izzby",
"uri": "/Terrago/2"
},
"status": {
"content": "<p>Some Content</p>",
"stage": 1
},
"alerts": {
"status": 2
},
"revenue": {
"value": 2573.13,
"compare": 0
},
"children": [{
"ctr": 79,
"averageECPC": 54,
"cost": 3554.78,
"margin": 88,
"profit": 3145.81,
"property": {
"value": "Comvex",
"uri": "/Octocore/4"
},
"status": {
"content": "<p>Some Content</p>",
"stage": 1
},
"alerts": {
"status": 2
},
"revenue": {
"value": 1247.92,
"compare": 0
}
}]
}
Now I want to search all objects in the array and return only objects which include a string of some sort, but I only want to search certain properties.
I basically have another array which contains the keys I want to search, e.g.
const iteratees = ['ctr', 'property.value', 'status.stage']
I have lodash available within the project, but I have no idea where to start.
Any ideas?
You could use filter(), some() and reduce() to do this.
const iteratees = ['ctr', 'property.value', 'status.stage'];
var searchFor = 'lo';
var result = arr.filter(function(o) {
return iteratees.some(function(e) {
var res = e.split('.').reduce(function(a, b) {
if(a) return a[b];
}, o);
if(res) {
if((res).toString().indexOf(searchFor) != -1) return true;
}
})
})
var arr = [{
"ctr": 'lorem',
"averageECPC": 23,
"cost": 2732.54,
"margin": 66,
"profit": 2495.9,
"property": {
"value": "Izzby",
"uri": "/Terrago/2"
},
"status": {
"content": "<p>Some Content</p>",
"stage": 1
},
"alerts": {
"status": 2
},
"revenue": {
"value": 2573.13,
"compare": 0
},
"children": [{
"ctr": 79,
"averageECPC": 54,
"cost": 3554.78,
"margin": 88,
"profit": 3145.81,
"property": {
"value": "Comvex",
"uri": "/Octocore/4"
},
"status": {
"content": "<p>Some Content</p>",
"stage": 1
},
"alerts": {
"status": 2
},
"revenue": {
"value": 1247.92,
"compare": 0
}
}]
}, {
name: 'lorem',
ctr: 12,
property: {
value: 1
},
status: {
stage: 1
}
}, {
name: 'ipsum'
}]
const iteratees = ['ctr', 'property.value', 'status.stage'];
var searchFor = 'lo';
var result = arr.filter(function(o) {
return iteratees.some(function(e) {
var res = e.split('.').reduce(function(a, b) {
if (a) return a[b];
}, o);
if (res) {
if ((res).toString().indexOf(searchFor) != -1) return true;
}
})
})
console.log(result)

Categories

Resources