How to pull nested object based on string match? - javascript

activePath would change dynamically based on api call , how to pull object based on the activePath string that matches in nested object ?
path examples : Drug/GetRefills in this case it should push data.Drug.getRefills and if path is Payment/getAccount it should push data.Payment.getAccount
main.js
const data =
[{
id: 11,
name: "Drug",
children: [{
id: 12,
name: "getRefills"
}, {
id: 13,
name: "getDetails"
}]
}, {
id: 14,
name: "Payment",
children: [{
id: 15,
name: "getAccount"
}, {
id: 16,
name: "getAccountDetails"
}]
}]
function getModelData(data){
var activePath = "Drug/GetRefills";
var _interfaces = [];
$.each(data, function(id, item){
if (activePath.toLowerCase().includes(item.name)) {
console.log('OBJ', item);
_interfaces.push(item); // it should push getrefills object into interfaces
}
});
return _interfaces;
}

You can use recursion to find the object (similar to DFS):
const data = [{
id: 11,
name: "Drug",
children: [{
id: 12,
name: "getRefills"
}, {
id: 13,
name: "getDetails"
}]
}, {
id: 14,
name: "Payment",
children: [{
id: 15,
name: "getAccount"
}, {
id: 16,
name: "getAccountDetails"
}]
}];
function getModelData(path) {
function find(arr, [key, ...rest]) {
const obj = arr.find(o => o.name === key);
if (!obj) return null;
return rest.length ? find(obj.children || [], rest) : obj;
}
return find(data, path.split('/'));
// Instead of returning, add the found object to _interfaces
}
console.log(getModelData('Drug/getRefills'));
console.log(getModelData('Drug/getRefillsss'));
console.log(getModelData('Payment/getAccountDetails'));

I think you are looking for some util like flat. Here is the very basic example.
const data = [
{
id: 11,
name: "Drug",
children: [
{
id: 12,
name: "getRefills"
},
{
id: 13,
name: "getDetails"
}
]
},
{
id: 14,
name: "Payment",
children: [
{
id: 15,
name: "getAccount"
},
{
id: 16,
name: "getAccountDetails"
}
]
}
];
function flat(array) {
return array.reduce((m, {name, children}) => {
children.forEach((child) => {
const {name:cname} = child
const fullName = `${name.toLowerCase()}/${cname.toLowerCase()}`
if(!m[fullName]) m[fullName] =[]
m[fullName].push(child)
})
return m
},{})
}
function getModelData(path, data) {
return flat(data)[path.toLowerCase()];
}
var activePath = "Drug/GetRefills";
console.log(getModelData(activePath, data));
//Output
[ { id: 12, name: 'getRefills' } ]

Here is an example how you can get the right object from the data with the filter function from lodash.
const activePath = "Drug/getRefills";
// get name
let name = activePath.substr(0, activePath.indexOf('/'));
// get detail
let detail = activePath.substr(activePath.indexOf('/') + 1);
const data =
[{
id: 11,
name: "Drug",
children: [{
id: 12,
name: "getRefills"
}, {
id: 13,
name: "getDetails"
}]
}, {
id: 14,
name: "Payment",
children: [{
id: 15,
name: "getAccount"
}, {
id: 16,
name: "getAccountDetails"
}]
}]
// Get data with lodash filter
const currentName = _.filter(data, d => d.name === name);
const currentDetail = _.filter(currentName[0].children, c => c.name === detail);
console.log(currentDetail[0]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

const data = [{
id: 11,
name: "Drug",
children: [{
id: 12,
name: "getRefills"
}, {
id: 13,
name: "getDetails"
}]
}, {
id: 14,
name: "Payment",
children: [{
id: 15,
name: "getAccount"
}, {
id: 16,
name: "getAccountDetails"
}]
}];
function getModelData(data,activePath){
var activePaths = activePath.split("/"),
_interfaces = [];
$.each(data, function(index, item){
if(!item.children || item.children.length == 0){
return false; //break
}
if(activePaths[0].toLowerCase() != item.name.toLowerCase()){
return true;//continue
}
childs = item.children;
$.each(childs,function(name,item){
item.name.toLowerCase() === activePaths[1].toLowerCase() && _interfaces.push(item);
});
});
return _interfaces;
}
console.log(getModelData(data,'Drug/getRefills'));
console.log(getModelData(data,'Payment/getAccountDetails'));

Related

Search for value contained in array of objects in property of object contained in array

can someone help me with this?
I need a function that given a fieldID, searchs within objects and returns the objectID that fieldID is in.
const objects = [
{
objectID: 11,
fields: [
{ id: 12, name: 'Source ID' },
{ id: 12, name: 'Source ID' },
],
},
{objectID: 14,
fields: [
{ id: 15, name: 'Creator' },
],},
{objectID: 16,
fields: [
{ id: 17, name: 'Type' },
{ id: 18, name: 'Name' },
{ id: 19, name: 'Description' },
],},
];
SOLVED:
Got it working like this:
const getObjectID = fieldId => {
for (const object of objects) {
if (object.fields.find(field => field.id === fieldId)) {
return object.objectID;
}
}
};
This will work:
const getObjectId = (fieldID) => {
const object = objects.find(object => object.fields.find(field => field.id === fieldID )!== undefined)
if(object) return object.objectID;
return null
}
Using the find array method:
const objects = [
{ objectId: 1, fields: ["aaa"] },
{ objectId: 2, fields: ["bbb"] },
{ objectId: 3, fields: ["ccc"] },
];
const getObjectId = (id) => objects.find(object.objectId === id);
console.log(getObjectId(2));
// { objectId: 2, fields: ["bbb"] }
Read more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

Cant retrieve the data from the Array by using method(passing) index as argument

Can't get the Array item by using method() while passing index as argument
it shows as undefined
export class DataService {
public list = [
{ id: 11, name: 'Mr. Nice' },
{ id: 12, name: 'Narco' },
{ id: 13, name: 'Bombasto' },
{ id: 14, name: 'Celeritas' },
{ id: 15, name: 'Magneta' },
{ id: 16, name: 'RubberMan' },
{ id: 17, name: 'Dynama' },
{ id: 18, name: 'Dr IQ' },
{ id: 19, name: 'Magma' },
{ id: 20, name: 'Tornado' }
]
getList() {
return this.list;
}
update(num, updated) {
let list = this.getList()
console.log(typeof (num))
console.log(this.list[num])
}
Your array contains objects, but you want to search by id which is a property of those objects. You have to use filter:
console.log(this.list.find(el => el.id === id))

deleting an element in nested array using filter() function

I have been trying to delete an element with an ID in nested array.
I am not sure how to use filter() with nested arrays.
I want to delete the {id: 111,name: "A"} object only.
Here is my code:
var array = [{
id: 1,
list: [{
id: 123,
name: "Dartanan"
}, {
id: 456,
name: "Athos"
}, {
id: 789,
name: "Porthos"
}]
}, {
id: 2,
list: [{
id: 111,
name: "A"
}, {
id: 222,
name: "B"
}]
}]
var temp = array
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < array[i].list.length; j++) {
temp = temp.filter(function(item) {
return item.list[j].id !== 123
})
}
}
array = temp
You can use the function forEach and execute the function filter for every array list.
var array = [{ id: 1, list: [{ id: 123, name: "Dartanan" }, { id: 456, name: "Athos" }, { id: 789, name: "Porthos" }] }, { id: 2, list: [{ id: 111, name: "A" }, { id: 222, name: "B" }] }];
array.forEach(o => (o.list = o.list.filter(l => l.id != 111)));
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
To remain the data immutable, use the function map:
var array = [{ id: 1, list: [{ id: 123, name: "Dartanan" }, { id: 456, name: "Athos" }, { id: 789, name: "Porthos" }] }, { id: 2, list: [{ id: 111, name: "A" }, { id: 222, name: "B" }] }],
result = array.map(o => ({...o, list: o.list.filter(l => l.id != 111)}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could create a new array which contains elements with filtered list property.
const result = array.map(element => (
{
...element,
list: element.list.filter(l => l.id !== 111)
}
));
You can use Object.assign if the runtime you are running this code on does not support spread operator.
Array.filter acts on elements:
var myArray = [{something: 1, list: [1,2,3]}, {something: 2, list: [3,4,5]}]
var filtered = myArray.filter(function(element) {
return element.something === 1;
// true = keep element, false = discard it
})
console.log(filtered); // logs [{something: 1, list: [1,2,3]}]
You can use it like this:
var array = [{
id: 1,
list: [{
id: 123,
name: "Dartanan"
}, {
id: 456,
name: "Athos"
}, {
id: 789,
name: "Porthos"
}]
}, {
id: 2,
list: [{
id: 111,
name: "A"
}, {
id: 222,
name: "B"
}]
}]
for (var i = 0; i < array.length; ++i) {
var element = array[i]
// Filter the list
element.list = element.list.filter(function(listItem) {
return listItem.id !== 111 && listItem.name !== 'A';
})
}
console.log(array)

Reorder array of objects based on attribute

I have an array of objects, each with an 'id' and a 'name'. I'm retrieving an 'id' from the server and need to reorder the array starting from this id.
Example code:
var myList = [
{
id: 0,
name: 'Joe'
},
{
id: 1,
name: 'Sally'
},
{
id: 2,
name: 'Chris'
},
{
id: 3,
name: 'Tiffany'
},
{
id: 4,
name: 'Kerry'
}
];
Given an 'id' of 2, how can I reorder the array so my output is as follows:
var newList = [
{
id: 2,
name: 'Chris'
},
{
id: 3,
name: 'Tiffany'
},
{
id: 4,
name: 'Kerry'
},
{
id: 0,
name: 'Joe'
},
{
id: 1,
name: 'Sally'
}
];
Try this:
function orderList(list, id){
return list.slice(id).concat(list.slice(0,id));
}
Link to demo
You could slice the array at given index and return a new array using spread syntax.
const myList = [{id:0,name:'Joe'},{id:1,name:'Sally'},{id:2,name:'Chris'},{id:3,name:'Tiffany'},{id:4,name:'Kerry'}];
const slice = (arr, num) => [...arr.slice(num), ...arr.slice(0, num)];
console.log(slice(myList, 2));
myList.sort(function(a,b){
return a.id>2===b.id>2?a.id-b.id:b.id-a.id;
});
newList=myList;
http://jsbin.com/kenobunali/edit?console
You could splice the wanted part and use splice to insert it at the end of the array.
var myList = [{ id: 0, name: 'Joe' }, { id: 1, name: 'Sally' }, { id: 2, name: 'Chris' }, { id: 3, name: 'Tiffany' }, { id: 4, name: 'Kerry' }],
id = 2;
myList.splice(myList.length, 0, myList.splice(0, myList.findIndex(o => o.id === id)));
console.log(myList);
using es6 spread syntax
var myList = [{ id: 0, name: 'Joe' }, { id: 1, name: 'Sally' }, { id: 2, name: 'Chris' }, { id: 3, name: 'Tiffany' }, { id: 4, name: 'Kerry' }],
id = 2;
var index = myList.findIndex(o => o.id == id);
var arr = myList.splice(0, index);
var result = [...myList, ...arr];
console.log(result);

Get missing objects from 2 arrays of objects

let selected = [
{id: 15, name: 'Canada'},
{id: 25, name: 'Germany'}
];
let all = [
{id: 15, name: 'Canada'},
{id: 25, name: 'Germany'},
{id: 32, name: 'United States'},
{id: 40, name: 'China'}
]
How do I get non-selected countries from all objects and print it out in another variable? Based on id key of those which are in selected array?
You need to find all objects that aren't contained in selected and then do something with them:
let nonSelectedItems = all.filter(obj => selected.every(s => s.id !== obj.id));
//do stuff with non-selected items
You can use filter and find, so as soon as element with same id is found in selected it will filter out that element from all. You can also use some instead of find.
let selected = [
{id: 15, name: 'Canada'},
{id: 25, name: 'Germany'}
];
let all = [
{id: 15, name: 'Canada'},
{id: 25, name: 'Germany'},
{id: 32, name: 'United States'},
{id: 40, name: 'China'}
]
var r = all.filter(e => !selected.find(a => e.id === a.id));
console.log(r)
Generate an object which holds id as a property using Array#reduce method(which helps to speed up since you need to iterate over and over) and use Array#filter method to filter elements from all array.
// generate the object reference
let ref = selected.reduce(function(obj, o) {
// define property
obj[o.id] = true;
// return object property
return obj;
// set initial value as an object
}, {});
// filter out array elements
let res = all.filter(function(o) {
return !ref[o.id]
})
let selected = [{
id: 15,
name: 'Canada'
}, {
id: 25,
name: 'Germany'
}];
let all = [{
id: 15,
name: 'Canada'
}, {
id: 25,
name: 'Germany'
}, {
id: 32,
name: 'United States'
}, {
id: 40,
name: 'China'
}]
let ref = selected.reduce(function(obj, o) {
obj[o.id] = true;
return obj;
}, {});
console.log(
all.filter(function(o) {
return !ref[o.id]
})
)
With ES6 arrow function :
let ref = selected.reduce((obj, o) => (obj[o.id] = true, obj), {});
let res = all.filter(o => !ref[o.id]);
let selected = [{
id: 15,
name: 'Canada'
}, {
id: 25,
name: 'Germany'
}];
let all = [{
id: 15,
name: 'Canada'
}, {
id: 25,
name: 'Germany'
}, {
id: 32,
name: 'United States'
}, {
id: 40,
name: 'China'
}]
let ref = selected.reduce((obj, o) => (obj[o.id] = true, obj), {});
console.log(
all.filter(o => !ref[o.id])
)

Categories

Resources