JS How to find result in nested objects [duplicate] - javascript

This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed 8 months ago.
The community reviewed whether to reopen this question 8 months ago and left it closed:
Original close reason(s) were not resolved
I have a nested Object that I need to iterate. The object looks like this:
{
"Page1": {
"path": "/page1"
},
"Page2": {
"path": "/account/menu/page1"
},
"Page3": {
"items": {
"Subpage1": {
"path": "/account/menu/subpage1"
},
"Subpage2": {
"path": "/account/menu/subpage2"
},
"Subpage3": {
"path": "/account/menu/subpage3"
}
}
},
"Page4": {
"items": {
"Subpage4": {
"path": "/account/menu/subpage4"
},
"Subpage5": {
"path": "/account/menu/subpage5"
},
...
I need to get the name of the specific subpage, based on the path of the user.
For example. If the user is on the page /account/menu/subpage2. I need to get the name Subpage2.
What I did is the following:
const currentPageName = getPageName(this.props?.match?.params.menu); //This function gets the name of the current page (Subpage2)
const getThePageName = = path => Object.keys(jsonData).find(el => jsonData[el]?.items && jsonData[el]?.items[currentPageName]?.path === path)
console.log("getThePageName", getThePageName("/account/menu/subpage2")));
The result of the above is Page3, but I need it to be Subpage2. What am I doing wrong and how to fix it?

Concept
Iterate through all the data entries and check if the path of any of these pages equal to the target path specified. Also within the loop, iterate through all of the pages' subpages and, again, check if the path of any of these subpages equal to the target path specified. If a match found then return the result as the key of the path's object.
Code
const data = {"Page1":{"path":"/page1"},"Page2":{"path":"/account/menu/page1"},"Page3":{"items":{"Subpage1":{"path":"/account/menu/subpage1"},"Subpage2":{"path":"/account/menu/subpage2"},"Subpage3":{"path":"/account/menu/subpage3"}}},"Page4":{"items":{"Subpage4":{"path":"/account/menu/subpage4"},"Subpage5":{"path":"/account/menu/subpage5"}}}};
function findPage(data,target){
let result;
Object.entries(data).forEach(page => {
if (page[1].path === target) result = page[0];
if (page[1].items){
Object.entries(page[1].items).forEach(subpage => {
if (subpage[1].path === target) result = subpage[0];
});
}
});
return result;
}
console.log(findPage(data,"/account/menu/subpage2"));
console.log(findPage(data,"/page1"));

Solution using recursion, can work with deeper level of "sub pages".
const data = { "Page1": { "path": "/page1" }, "Page2": { "path": "/account/menu/page1" }, "Page3": { "items": { "Subpage1": { "path": "/account/menu/subpage1" }, "Subpage2": { "path": "/account/menu/subpage2" }, "Subpage3": { "path": "/account/menu/subpage3" } } }, "Page4": { "items": { "Subpage4": { "path": "/account/menu/subpage4" }, "Subpage5": { "path": "/account/menu/subpage5" }, "Subpage6": { "items": { "Subsubpage1": { "path": "/secret" } } } } } };
function getPageNameForPath(data, path) {
for (const pageName in data) {
if (data[pageName].path != null) {
if (data[pageName].path === path) {
return pageName;
}
} else {
const found = getPageNameForPath(data[pageName].items, path);
if (found) {
return found;
}
}
}
}
console.log(getPageNameForPath(data, '/account/menu/subpage2'));
console.log(getPageNameForPath(data, '/account/menu/page1'));
console.log(getPageNameForPath(data, '/secret'));

here is some piece of code
const jsonData = { "Page1": { "path": "/page1" }, "Page2": { "path": "/account/menu/page1" }, "Page3": { "items": { "Subpage1": { "path": "/account/menu/subpage1" }, "Subpage2": { "path": "/account/menu/subpage2" }, "Subpage3": { "path": "/account/menu/subpage3" } } }, "Page4": { "items": { "Subpage4": { "path": "/account/menu/subpage4" }, "Subpage5": { "path": "/account/menu/subpage5" }, } } };
const currentPageName = 'Subpage2';
const getThePageName = path => Object.keys(jsonData).reduce((acc, el) => {
if (acc?.length) {
return acc;
}
if (jsonData[el].hasOwnProperty('items')) {
if (jsonData[el]?.items?.[currentPageName]?.path === path) {
console.log(path, jsonData[el]?.items?.[currentPageName]?.path)
acc = currentPageName;
}
} else {
if (jsonData[el].path === path) {
console.log(path, jsonData[el].path, path)
acc = el;
}
}
return acc;
}, undefined);
console.log("getThePageName", getThePageName("/account/menu/subpage2"));

Related

Get values for a matching key recursively from object

I have this json object
{
"data": {
"user": {
"user_info": {
"id": "AoGC2HQ9vedHmzcMX"
},
"product": [
{
"node": {
"id": "NzcxNzU2ODU1ODM1",
"feedback": {
"raters": {
"nodes": [
{
"id": "1",
"name": "Dan"
},
{
"id": "2",
"name": "Allen"
},
{
"id": "3",
"name": "Williams"
}
]
},
"commentors": {
"nodes": [
{
"id": "001",
"name": "Kent"
},
{
"id": "002",
"name": "Jay"
}
]
}
}
}
}
]
}
}
}
So how do I make it to get values of id If the parent property matches the desired key name, In this example I want to get all id's from raters.nodes only.
so expected result is
[1,2,3]
I know can do obj.data.user.product[0].node.feedback.raters.nodes and loop through that, but that is not how I want and the object tree occasionally changes.
I have used this recursive function
const recursiveSearch = (obj, searchKey, results = []) => {
const r = results;
Object.keys(obj).forEach(key => {
const value = obj[key];
if(key === searchKey && typeof value !== 'object'){
r.push(value);
}else if(typeof value === 'object'){
recursiveSearch(value, searchKey, r);
}
});
return r;
};
//returns all id's
While it works, it returns all id values, so how do I improve it? If not, how do I make this possible?
I think you want to really do this in 2 steps,..
First make a function to get the root node your looking for, and then you can just use map like normal.
Below is an example.
var data = JSON.parse("{\"data\":{\"user\":{\"user_info\":{\"id\":\"AoGC2HQ9vedHmzcMX\"},\"product\":[{\"node\":{\"id\":\"NzcxNzU2ODU1ODM1\",\"feedback\":{\"raters\":{\"nodes\":[{\"id\":\"1\",\"name\":\"Dan\"},{\"id\":\"2\",\"name\":\"Allen\"},{\"id\":\"3\",\"name\":\"Williams\"}]},\"commentors\":{\"nodes\":[{\"id\":\"001\",\"name\":\"Kent\"},{\"id\":\"002\",\"name\":\"Jay\"}]}}}}]}}}");
function getRoot(data, search) {
function get(path, data) {
for (const [k, v] of Object.entries(data)) {
if (v instanceof Object) {
const pp = `${path}.${k}`;
if (pp.slice(-search.length) === search) {
return v;
}
const r = get(`${path}.${k}`, v);
if (r) return r;
}
}
}
return get('', data);
}
const r = getRoot(data, 'raters.nodes');
console.log(r && r.map(i => i.id));

Skip JSON.map() for the subsequent elements

DEMO
(Please check the browser console for output)
I have a JSON customerItemResponse in a format
{
"totalResults": someNumber,
"results": [
{
"totalItem": 406,
"customerId": "10000"
},
{
"totalItem": 468,
"customerId": "10001"
},
{
"totalItem": 20,
"customerId": "10002"
},
...
Then I have another JSON customerInfo:
{
"totalResults": someNumber,
"results": [
{
"customerId": "10000",
"region": "4",
"area": "42",
},
{
"customerId": "10001",
"region": "4",
"area": "43",
},
{
"customerId": "10002",
"region": "5",
"area": "52",
},
Now I have to create a JSON in a format
[
{
region:'4'
regionDetails:[
{
area:'42'
customerDetails:[
{
customerId:'10000'
totalItem:406
},
{
customerId:'10005'
totalItem:301
},
]
},
{
area:'11'
customerDetails:[
{
customerId:'10010'
totalItem:11
},
{
customerId:'10021'
totalItem:105
},
]
},
]
},
{
region:'5'
regionDetails:[
{
area:'52'
customerDetails:[
{
customerId:'10002'
totalItem:52
},
{
customerId:'10027'
totalItem:310
},
]
},
{
area:'41'
customerDetails:[
{
customerId:'10017'
totalItem:109
},
{
customerId:'10041'
totalItem:450
},
]
},
]
}
]
This is the logic I have written:
customerData=<CustomerDataInterface[]>[]
mapJson() {
this.customerItemResponse.map((res, index) => {
this.customerInfo.find((obj) => {
if (obj.customerId == res.customerId) {
this.customerData.length
? this.customerData.map((data, index1) => {
if (data.region == obj.region) {
data.regionDetails.length
? data.regionDetails.map((regDetails, index2) => {
if (regDetails.area == obj.area) {
regDetails.dealerDetails.push({
customerId: obj.customerId,
totalItem: res.totalItem,
});
return;
}
if (index2 == data.regionDetails.length - 1) {
data.regionDetails.push({ area: obj.area, dealerDetails: [] });
}
})
: data.regionDetails.push({ area: obj.area, dealerDetails: [] });
return;
}
if (index1 == this.customerData.length - 1) {
this.customerData.push({ region: obj.region, regionDetails: [] });
}
})
: this.customerData.push({ region: obj.region, regionDetails: [] });
}
});
});
console.log(this.customerData);
}
Now the output of the console has several region repeated. And suppose if I have 6 unique region but the this.customerData.length is 31.
I think return; is not working as expected. And is not skipping the subsequent element.
here is an efficient way to resolving the issue using js Maps. We can build maps with info about corresponding region and then areas. and after the data is built into maps - convert it back to simple js structures, such as object and arrays
mapJson() {
const customerToTotalMap = new Map(this.customerItemResponse.map(({customerId, totalItem}) => [customerId, totalItem]));
const regionsMap = new Map();
for(let {customerId, region, area} of this.customerInfo) {
let regionAreas;
if(regionsMap.has(region)) {
regionAreas = regionsMap.get(region);
} else {
regionAreas = new Map();
regionsMap.set(region, regionAreas);
}
let areaInfo;
if(regionAreas.has(area)) {
areaInfo = regionAreas.get(area);
} else {
areaInfo = [];
regionAreas.set(area, areaInfo);
}
areaInfo.push({customerId, totalItem: customerToTotalMap.get(customerId)});
}
this.customerData = [...regionsMap.entries()].map(([region, areas]) => ({
region,
regionDetails: [...areas.entries()].map(([area, customerDetails]) => ({
area,
customerDetails
}))
}))
console.log(this.customerData);
}
This is similar to #Andrei's answer. It creates an object literal as mapper. Also, it uses mapping between the region and area when they are created. So, finally you can just get the values of the regionMapper object without going through the mapper objects again
const customerItemResponse=[{customerId:10000,totalItem:77},{customerId:10001,totalItem:37},{customerId:10002,totalItem:295},{customerId:10003,totalItem:458},{customerId:10004,totalItem:248},{customerId:10005,totalItem:35},{customerId:10006,totalItem:280},{customerId:10007,totalItem:147},{customerId:10008,totalItem:439},{customerId:10009,totalItem:401},{customerId:10010,totalItem:489},{customerId:10011,totalItem:414},{customerId:10012,totalItem:287},{customerId:10013,totalItem:391},{customerId:10014,totalItem:125},{customerId:10015,totalItem:207},{customerId:10016,totalItem:197},{customerId:10017,totalItem:151},{customerId:10018,totalItem:225},{customerId:10019,totalItem:333},{customerId:10020,totalItem:361},{customerId:10021,totalItem:225},{customerId:10022,totalItem:242},{customerId:10023,totalItem:150},{customerId:10024,totalItem:52},{customerId:10025,totalItem:475},{customerId:10026,totalItem:494},{customerId:10027,totalItem:30},{customerId:10028,totalItem:189},{customerId:10029,totalItem:112},{customerId:10030,totalItem:482},{customerId:10031,totalItem:283},{customerId:10032,totalItem:159},{customerId:10033,totalItem:440},{customerId:10034,totalItem:461},{customerId:10035,totalItem:76},{customerId:10036,totalItem:84},{customerId:10037,totalItem:392},{customerId:10038,totalItem:296},{customerId:10039,totalItem:293},{customerId:10040,totalItem:135},{customerId:10041,totalItem:348},{customerId:10042,totalItem:338},{customerId:10043,totalItem:444},{customerId:10044,totalItem:15},{customerId:10045,totalItem:32},{customerId:10046,totalItem:67},{customerId:10047,totalItem:277},{customerId:10048,totalItem:65},{customerId:10049,totalItem:95},{customerId:10050,totalItem:290}],
customerInfo=[{customerId:10000,region:"3",area:"32"},{customerId:10001,region:"2",area:"22"},{customerId:10002,region:"2",area:"25"},{customerId:10003,region:"3",area:"31"},{customerId:10004,region:"2",area:"25"},{customerId:10005,region:"1",area:"11"},{customerId:10006,region:"1",area:"14"},{customerId:10007,region:"5",area:"55"},{customerId:10008,region:"5",area:"51"},{customerId:10009,region:"4",area:"45"},{customerId:10010,region:"1",area:"14"},{customerId:10011,region:"1",area:"12"},{customerId:10012,region:"3",area:"33"},{customerId:10013,region:"2",area:"25"},{customerId:10014,region:"4",area:"41"},{customerId:10015,region:"3",area:"32"},{customerId:10016,region:"5",area:"55"},{customerId:10017,region:"2",area:"23"},{customerId:10018,region:"3",area:"33"},{customerId:10019,region:"5",area:"51"},{customerId:10020,region:"4",area:"42"},{customerId:10021,region:"1",area:"12"},{customerId:10022,region:"1",area:"14"},{customerId:10023,region:"1",area:"14"},{customerId:10024,region:"1",area:"13"},{customerId:10025,region:"4",area:"45"},{customerId:10026,region:"3",area:"34"},{customerId:10027,region:"2",area:"24"},{customerId:10028,region:"4",area:"45"},{customerId:10029,region:"2",area:"22"},{customerId:10030,region:"2",area:"22"},{customerId:10031,region:"2",area:"21"},{customerId:10032,region:"3",area:"33"},{customerId:10033,region:"1",area:"11"},{customerId:10034,region:"3",area:"33"},{customerId:10035,region:"3",area:"32"},{customerId:10036,region:"2",area:"22"},{customerId:10037,region:"4",area:"41"},{customerId:10038,region:"3",area:"31"},{customerId:10039,region:"5",area:"51"},{customerId:10040,region:"2",area:"23"},{customerId:10041,region:"4",area:"45"},{customerId:10042,region:"1",area:"14"},{customerId:10043,region:"5",area:"54"},{customerId:10044,region:"3",area:"34"},{customerId:10045,region:"5",area:"51"},{customerId:10046,region:"4",area:"42"},{customerId:10047,region:"5",area:"53"},{customerId:10048,region:"1",area:"11"},{customerId:10049,region:"3",area:"35"},{customerId:10050,region:"5",area:"51"}];
const customerItemMapper = {}
for (const c of customerItemResponse)
customerItemMapper[c.customerId] = c.totalItem
const regionMapper = {},
areaMapper = {};
for (const { customerId, region, area } of customerInfo) {
let regionKey = `Region_${region}`,
areaKey = `Area_${area}`,
totalItem = customerItemMapper[customerId];
if (!(regionKey in regionMapper))
regionMapper[regionKey] = { region, regionDetails: [] }
if (!(areaKey in areaMapper)) {
const o = { area, customerDetails: [] }
areaMapper[areaKey] = o;
regionMapper[regionKey].regionDetails.push(o) // area-region relation
}
areaMapper[areaKey].customerDetails.push({ customerId, totalItem })
}
console.log(Object.values(regionMapper))

How to access a nested key in json using javascript

So, i have this json file, in which i have to take out the fileName tag, and use it.
{
"dataset": {
"private": false,
"stdyDscr": {
"citation": {
"titlStmt": {
"titl": "Smoke test",
"IDNo": {
"text": "10.5072/FK2/WNCZ16",
".attrs": {
"agency": "doi"
}
}
},
"rspStmt": {
"AuthEnty": "Dataverse, Admin"
},
"biblCit": "Dataverse, Admin, 2015, \"Smoke test\", http://dx.doi.org/10.5072/FK2/WNCZ16, Root Dataverse, V1 [UNF:6:iuFERYJSwTaovVDvwBwsxQ==]"
}
},
"fileDscr": {
"fileTxt": {
"fileName": "fearonLaitinData.tab",
"dimensns": {
"caseQnty": "6610",
"varQnty": "69"
},
"fileType": "text/tab-separated-values"
},
"notes": {
"text": "UNF:6:K5wLrMhjKoNX7znhVpU8lg==",
".attrs": {
"level": "file",
"type": "VDC:UNF",
"subject": "Universal Numeric Fingerprint"
}
},
".attrs": {
"ID": "f6"
}
}
},
im using d3.js mostly, but some parts of jquery and javascript with it. right now im doing:
d3.json(url,function(json){
var jsondata=json;
var temp = jsondata.dataset.fileDscr.fileTxt.fileName;
}
Is there a way to just access fileName directly? Im asking because, i have to make this generic to fit other json files, where the nesting might be different.
This will return the value for some instance of the key in the JSON data, if it exists.
var data = {...};
function findValue(json, key) {
if (key in json) return json[key];
else {
var otherValue;
for (var otherKey in json) {
if (json[otherKey] && json[otherKey].constructor === Object) {
otherValue = findValue(json[otherKey], key);
if (otherValue !== undefined) return otherValue;
}
}
}
}
console.log(findValue(data, 'fileName'));
It will return a comma separated string of all the values of a specified key
function walk(obj,keyname) {
var propertyVal="";
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
var val = obj[key];
if(typeof(val) == 'object') {
console.log(val);
propertyVal+= walk(val,keyname);
}else {
if(key == keyname){
propertyVal = propertyVal+","+obj[key];
}
}
}
}
return propertyVal;
}
alert(walk(data,'filename').replace(',',''));

Compare two arrays and update with the new values by keeping the existing objects using javascript

Below are my two arrays .I want to compare them and the resultant array should contain the updated values.Id's are common..
The arrays spans to n levels ie., there is no fixed levels..
The first array ie., the array before updation..
var parentArray1=[
{
"id": 1,
"name": "test",
"context": [
{
"id": 1.1,
"name": "test 1.1"
}
]
},
{
"id": 2,
"name": "test"
},
{
"id": 3,
"name": "test",
"context": [
{
"id": 3.1,
"name": "test 3.1"
}
]
},
{
"id": 4,
"name": "test"
}
]
The operations that i performed are
1.Adding a new Item
2.Updating an existing item
As a result of these two operations the changed values I will be getting in a different array..
ie.,
var changedArray=
[
{
"id": 1,
"name": "test1",
"context": [
{
"id": 1.1,
"name": "Changed test 1.1"
}
]
},
{
"id": 5,
"name": "test5"
}
]
Now I have written a generic function that loops through the parentArray1 and using the unique propertiesI need to either add a new item,if the item is there in the changedArray or update an existing item at any level
The resultant array should be ..
[
{
"id": 1,
"name": "test",
"context": [
{
"id": 1.1,
"name": "Changed test 1.1"
}
]
},
{
"id": 2,
"name": "test"
},
{
"id": 3,
"name": "test",
"context": [
{
"id": 3.1,
"name": "test 3.1"
}
]
},
{
"id": 4,
"name": "test"
},
{
"id": 5,
"name": "test5"
}
]
Generic function:
compareArray(parentArray1, changedArray, ["id"]);
function compareArray(array1, array2, propertyArray) {
var newItem = new Array();
array2.map(function(a1Item) {
array1.map(function(a2Item) {
/ If array loop again /
if (a2Item.constructor === Array) {
compareArray(a2Item, a1Item)
} else {
/ loop the property name to validate /
propertyArray.map(function(property) {
if (a2Item[property]) {
if (a2Item[property] === a1Item[property]) {
a2Item = a1Item
} else {
var isAvailable = _.find(newItem, function(item) {
return item[property] === a1Item[property]
})
if (!isAvailable) {
newItem.push(a1Item);
}
}
}
})
}
});
});
/ Insert the new item into the source array /
newItem.map(function(item) {
array1.push(item);
});
console.log("After Compare : " + array1);
}
I suggest to use a temporary object for the reference to the id and update if exist or push if not exist.
var parentArray1 = [{ "id": 1, "name": "test", "context": [{ "id": 1.1, "name": "test 1.1" }] }, { "id": 2, "name": "test" }, { "id": 3, "name": "test", "context": [{ "id": 3.1, "name": "test 3.1" }] }, { "id": 4, "name": "test" }],
changedArray = [{ "id": 1, "name": "test1", "context": [{ "id": 1.1, "name": "Changed test 1.1" }] }, { "id": 5, "name": "test5" }];
function insert(array, data) {
function iter(array) {
array.forEach(function (a) {
if (!('id' in a)) {
return;
}
if (o[a.id] !== a) {
o[a.id] = a;
}
Object.keys(a).forEach(function (k) {
Array.isArray(a[k]) && iter(a[k]);
});
});
}
var o = {};
iter(array);
data.forEach(function (a) {
if (o[a.id]) {
Object.keys(a).forEach(function (k) {
o[a.id][k] = a[k];
});
return;
}
array.push(a);
});
}
insert(parentArray1, changedArray);
document.write('<pre>' + JSON.stringify(parentArray1, 0, 4) + '</pre>');
This is what I came up with:
function sameKeys(o1, o2, keys) {
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (!o1.hasOwnProperty(key) || !o2.hasOwnProperty(key))
throw 'compared objects do not have the key ' + key;
if (o1[key] !== o2[key])
return false;
}
return true;
}
function isNothing(o) {
return typeof(o) === 'undefined' || o === null;
}
// this does not work if objects have functions as properties
function clone(o) {
if (isNothing(o))
return o;
return JSON.parse(JSON.stringify(o));
}
function extend(o1, o2, keys) {
if (isNothing(o2))
return;
if (isNothing(o1))
throw ('first parameter cannot be empty');
if (typeof(o1) != 'object' || typeof(o2) != 'object')
throw ('extend only works on objects');
Object.keys(o2).forEach(function (key) {
var newVal = o2[key];
if (o1.hasOwnProperty(key)) {
if (isNothing(newVal)) {
delete o1[key];
} else
if (Array.isArray(newVal)) {
compareArray(o1[key], newVal, keys);
} else {
switch (typeof(newVal)) {
case 'object':
extend(o1[key], newVal, keys);
break;
case 'boolean':
case 'number':
case 'string':
o1[key] = newVal;
break;
default:
throw 'not supported property type: ' + typeof(newVal);
}
}
} else {
o1[key] = clone(newVal);
}
});
}
function removeFromArray(arr, ids, keyArray) {
var indexes = [];
var it1s = arr.forEach(function (it, idx) {
if (sameKeys(ids, it, keyArray)) {
indexes.push(idx);
} else {
Object.keys(it).forEach(function (key) {
var newVal = it[key];
if (Array.isArray(newVal)) {
removeFromArray(it[key], ids, keyArray);
}
});
}
});
if (indexes.length) {
if (indexes.length > 1)
throw 'found multiple possible objects for the same key combination'
arr.splice(indexes[0], 1);
}
}
function compareArray(a1, a2, keyArray) {
a2.forEach(function (it2) {
var it1s = a1.filter(function (it) {
return sameKeys(it2, it, keyArray);
});
var it1;
if (!it1s.length) {
it1 = clone(it2);
a1.push(it1);
} else {
if (it1s.length > 1)
throw 'found multiple possible objects for the same key combination'
it1 = it1s[0];
extend(it1, it2, keyArray);
}
if (it2.removedIds) {
it2.removedIds.forEach(function (ids) {
removeFromArray(a1, ids, keyArray);
});
}
});
}
Use it with compareArray(parentArray1,changedArray,['id']);
Note that it would not work with objects that contain functions. Also, if the arrays would be large, perhaps a better solution is to sort both arrays by key, then always look from the last found object up. That's all I got for now.
Updated it with some concepts from Nina and some clearing of the code.
As I understood it, you only want to add properties. So extend({a: {b: 2}},{a:{c:3}}) will result in {a: {b:2,c:3}}. If this is not what you wanted, let me know.
I also added functionality for removing ids. If any of the objects in the array contains a removedIds array of the form [{id: 4},{id: 5}] then the items with those ids will be removed from the original array.
Slight modification on code, to satisfy your conditions. Try it!
function compareArray(originalArray, destinationArray, propertyArray) {
var newItem = new Array(), processedItem = new Array();
for (var i = 0; i < originalArray.length; i++) {
var sourceElement = originalArray[i];
for (var j = 0; j < destinationArray.length; j++) {
var destinationElement = destinationArray[j];
var isUpdated = false;
if (sourceElement.constructor === Array) {
compareArray(sourceElement, destinationElement, propertyArray);
} else {
/* loop the property name to validate */
propertyArray.map(function(property) {
if (sourceElement[property]) {
if (sourceElement[property] === destinationElement[property]) {
originalArray[i] = _.clone(destinationElement);
isUpdated = true;
return;
} else {
var isAvailable = _.find(newItem, function(item) {
return item[property] === destinationElement[property];
});
if (!isAvailable) {
var isAlreadyProcessed = _.find(processedItem, function(item) {
return item[property] === destinationElement[property];
});
if(!isAlreadyProcessed){
newItem.push(destinationElement);
}
}
}
}
});
}
if (isUpdated === true) {
break;
}
}
processedItem.push(sourceElement);
}
newItem.map(function(item) {
originalArray.push(item);
});
return originalArray;
}

Delete certain parts of json array

I'd like to create a new JSON array based on certain values.
Sample JSON:
var array =
{
"entries": {
"houses": [
{
"category": {
"category_id":"1",
"category_foo":"bar",
},
"important": {
"important_foo":"bar",
"dontforget":"me",
}
},
{
"category": {
"category_id":"1",
"category_foo":"bar",
},
"important": {
"important_foo":"bar",
"dontforget":"me",
}
},
"category": {
"category_id":"2",
"category_foo":"bar",
},
"important": {
"important_foo":"bar",
"dontforget":"me",
}
}
]
}
}
Now I need a way to search through this array and create a new array with all houses that have a category with category_id=1. Of course it should keep all the rest of the infos like important.
The new array should look like:
{
"entries": {
"houses": [
{
"category": {
"category_id":"1",
"category_foo":"bar",
},
"important": {
"important_foo":"bar",
"dontforget":"me",
}
},
{
"category": {
"category_id":"1",
"category_foo":"bar",
},
"important": {
"important_foo":"bar",
"dontforget":"me",
}
}
]
}
}
Any help is appreciated!
You can use Array.filter to do this:
var filteredResults = array.entries.houses.filter(function(house) {
return house.category && house.category_id == 1;
});
This code works.
var houses = array.entries.houses;
var newHouses = [];
for (var i = 0; i < houses.length; i++)
{
if (houses[i].category.category_id == "1") {
newHouses.push(houses[i]);
}
}
Check this out: https://jsfiddle.net/2u13phw3/

Categories

Resources