how to get new array newSelect using map ,forEach
const selects = [false, true, true, true, false];
const oldSelects = [
{ select: true, name: 'AA' },
{ select: true, name: 'AA' },
{ select: true, name: 'AA' },
{ select: true, name: 'AA' },
{ select: true, name: 'AA' },
];
const newSelect = [
{ select: false, name: 'AA' },
{ select: true, name: 'AA' },
{ select: true, name: 'AA' },
{ select: true, name: 'AA' },
{ select: false, name: 'AA' },
];
oldSelects[0].select === selects[0]
#Inder answer is great, but a map looks more clean imo:
const selects = [false, true, true, true, false];
const oldSelects = [{
select: true,
name: "AA"
},
{
select: true,
name: "AA"
},
{
select: true,
name: "AA"
},
{
select: true,
name: "AA"
},
{
select: true,
name: "AA"
}
];
const newSelect = oldSelects.map((el, i) => ({
select: selects[i],
name: el.name
}));
console.log(newSelect);
Hey you can map the old array to a new one.
const selects = [false, true, true, true, false];
const oldSelects = [{
select: true,
name: 'AA'
},
{
select: true,
name: 'AA'
},
{
select: true,
name: 'AA'
},
{
select: true,
name: 'AA'
},
{
select: true,
name: 'AA'
},
];
const newSelect = oldSelects.map((object, index) => {
object['select'] = selects[index]
return object;
})
console.log(newSelect)
Using forEach
const selects = [false, true, true, true, false];
const oldSelects = [{
select: true,
name: 'AA'
},
{
select: true,
name: 'AA'
},
{
select: true,
name: 'AA'
},
{
select: true,
name: 'AA'
},
{
select: true,
name: 'AA'
},
];
const newSelects = []
oldSelects.forEach((selectItem, index) => newSelects.push({...selectItem, select: selects[index]}))
console.log(newSelects)
Using map
const selects = [false, true, true, true, false];
const oldSelects = [{
select: true,
name: 'AA'
},
{
select: true,
name: 'AA'
},
{
select: true,
name: 'AA'
},
{
select: true,
name: 'AA'
},
{
select: true,
name: 'AA'
},
];
const newSelects = oldSelects.map((selectItem, index) => ({...selectItem, select: selects[index]}))
console.log(newSelects)
Related
I have a request
const request=additionalFields: [
{ field: 'PHONE', required: true },
{ field: 'COMPANY', required: true },
{ field: 'MOBILE', required: true },
{ field: 'COUNTRY', required: true }
]
the response i am getting is this
"additionalFields":
{
'PHONE':true,
'COMPANY':true,
'MOBILE':true,
'COUNTRY':true
}
i am not sure how to compare them. i kind of wrote something but even to me it looks wrong
const fields = request["additionalFields"];
for (let i = 0, len = fields.length; i < len; i++) {
expect(request.additionalFields[i].required).to.eql(
response.additionalFields
);
Here's another way. Just filter out anything that doesn't match up, then you'll have an array of differences if there are any.
const request={
additionalFields: [
{ field: 'PHONE', required: true },
{ field: 'COMPANY', required: true },
{ field: 'MOBILE', required: true },
{ field: 'COUNTRY', required: true }
]
}
const incoming = {
"additionalFields": {
'PHONE': true,
'COMPANY': true,
'MOBILE': false,
'COUNTRY': true
}
}
let differences = request.additionalFields.filter(f => incoming.additionalFields[f.field] !== f.required)
console.log(differences)
const request = [
{ field: 'PHONE', required: true },
{ field: 'COMPANY', required: true },
{ field: 'MOBILE', required: true },
{ field: 'COUNTRY', required: true }
]
const response = {"additionalFields":
{
'PHONE':true,
'COMPANY':true,
'MOBILE':true,
'COUNTRY':true
}}
for (const [key, value] of Object.entries(response['additionalFields'])) {
const {required, field} = request.find(({field}) => key === field);
if(required === value) { // here you can compare
console.log(key, field, value);
}
}
You need to dereference the response.additionalFields object using the value of field from each entry in request.additionalFields. Something like
for(const { field, required } of request.additionalFields) {
expect(required).to.eql(
response.additionalFields[field]
);
}
You should loop over each field detail in the request and compare the value against the response. Here you go:
const request = {
additionalFields: [
{ field: 'PHONE', required: true },
{ field: 'COMPANY', required: true },
{ field: 'MOBILE', required: true },
{ field: 'COUNTRY', required: true },
],
};
const response = {
additionalFields: {
PHONE: true,
COMPANY: true,
MOBILE: true,
COUNTRY: true,
},
};
for (let f of request.additionalFields) {
// Observe f is like { field:'PHONE', required: true }
// Next two lines are just for test, please remove and uncomment last one in your use case.
const comparisonResult = f.required === response.additionalFields[f.field];
console.log(`for field ${f.field}, It's ${comparisonResult}`);
// expect(f.required).to.eql(response.additionalFields[f.field]);
}
You can further improve readability by using destructuring, drop a comment if you want to see that.
You can use the for...of syntax to do this.
Here's the documentation.
const request = {
additionalFields: [
{ field: 'PHONE', required: true },
{ field: 'COMPANY', required: true },
{ field: 'MOBILE', required: true },
{ field: 'COUNTRY', required: true }
]
};
const response = {
additionalFields: {
PHONE:true,
COMPANY:true,
MOBILE: true,
COUNTRY:true
}
}
const requestFields = request['additionalFields'];
const responseFields = response['additionalFields'];
for(const { required, field } of requestFields) {
expect(required).to.eql(responseFields[field]);
}
The following is a sample that yields the desired output.
const data = [
{ itemID: '300', status: 'active', inventoryFlag: true, certifiedFlag: false, donateFlag: true },
{ itemID: '400', status: 'inactive', inventoryFlag: true, certifiedFlag: true, donateFlag: false },
{ itemID: '500', status: 'active', inventoryFlag: false, certifiedFlag: false, donateFlag: false },
{ itemID: '600', status: 'active', inventoryFlag: false, certifiedFlag: true, donateFlag: true },
{ itemID: '700', status: 'inactive', inventoryFlag: false, certifiedFlag: true, donateFlag: false }
];
document.getElementById("data").innerText = JSON.stringify(data.filter(o => o.inventoryFlag || o.donateFlag));
<textarea id="data" rows="50" cols="100"></textarea>
I'm trying to find a way to list the filter-by flags in a separate array and then use that in the .filter() somehow to get the same result set as the above code.
For example, here are the flags to use for filtering AND at least one of the values must be true in the object to be included in the final dataset -
const flags = ['inventoryFlag', 'donateFlag'];
As a start, I tried this but it didn't do anything:
const filteredData = data.filter(o => flags.includes(Object.keys(o)));
Inside of the filter, use the some method to detect if any of the property keys of an entry, that are contained in the flags array, have the a value of true.
const data = [
{ itemID: '300', status: 'active', inventoryFlag: true, certifiedFlag: false, donateFlag: true },
{ itemID: '400', status: 'inactive', inventoryFlag: true, certifiedFlag: true, donateFlag: false },
{ itemID: '500', status: 'active', inventoryFlag: false, certifiedFlag: false, donateFlag: false },
{ itemID: '600', status: 'active', inventoryFlag: false, certifiedFlag: true, donateFlag: true },
{ itemID: '700', status: 'inactive', inventoryFlag: false, certifiedFlag: true, donateFlag: false }
];
const flags = ['inventoryFlag', 'donateFlag'];
const result = data.filter(entry =>
flags.some(flag => entry[flag] === true)
);
console.log(result);
I have a menu array called "items".
It has submenus.
I need to filter the items with property "visible" equal 1.
I don't know at run time how deep the hierarchy will be.
I need a function returning a new array, with the next conditions:
Every non-matching object with no children, or no matches in children hierarchy, should not exist in output object
Every object with a descendant that contains a matching object, should remain
Only descendants with matching objects should remain
My question is similar to this post Recursively filter array of objects.
But it does not work to me.
I have used the following function, but it´s not working:
const items = [ { icon: "mdi-view-dashboard", title: "Dashboard", to: "/", visible: 1, },
{ title: "Manutenção", icon: "mdi-hammer-screwdriver", to: "", visible: 1,
items: [
{ title: "Usuários", icon: "mdi-account", to: "/usuarios", visible: 1, },
{ title: "Cores", to: "", visible: 1,
items: [
{ title: "Cores da Fila", icon: "mdi-eyedropper-variant", to: "/coresfila", visible: 1, },
{ title: "Cores da Agenda", icon: "mdi-palette", to: "/coresagenda", visible: 1, },
],
},
{ title: "Tabelas Médicas", to: "", visible: 1,
items: [
{ title: "Convênios", icon: "mdi-clipboard-outline", to: "/convenios", visible: 1, },
{ title: "Planos", icon: "mdi-plus-box", to: "/planos", visible: 1, },
{ title: "Especialidades", icon: "mdi-format-font", to: "/especialidadescompletas", visible: 1, },
{ title: "Modelos de Atestados", icon: "mdi-account-details-outline", to: "/modelosAtestados", visible: 1, },
{ title: "Modelos de Prescrições", icon: "mdi-account-edit-outline", to: "/modelosPrescricoes", },
{ title: "Cid-10", icon: "mdi-alphabetical", to: "/cid10", visible: 1, },
{ title: "Procedimentos", icon: "mdi-alarm-plus", to: "/procedimentos", visible: 1, },
{ title: "Materiais", icon: "mdi-table-of-contents", to: "/materiais", visible: 1, },
{ title: "Medicamentos", icon: "mdi-water", to: "/medicamentos", visible: 1, },
{ title: "Taxas", icon: "mdi-cash-100", to: "/taxas", visible: 1, },
],
},
],
},
{ title: "Empresa", icon: "mdi-cash-100", to: "", visible: 1,
items: [ { title: "Perfil da Empresa", icon: "mdi-account-network-outline", to: "/perfilempresa", visible: 1, },
{ title: "Créditos SMS", icon: "mdi-cash-usd-outline", to: "/creditossms", visible: 1, },
],
},
{ title: "Clientes", icon: "mdi-account-alert-outline", to: "/clientes", visible: 1, },
{ title: "Agenda", icon: "far fa-calendar-check", to: "/agenda", visible: 1, },
{ title: "Fila", icon: "mdi-account-multiple-check", to: "/fila", visible: 1, },
{ title: "Atendimento Médico", icon: "fas fa-user-md", to: "/atendimento", visible: 1, },
{ title: "Tela de Chamadas", icon: "mdi-play-network-outline", to: "/telao", visible: 1, },
{ title: "DICOM", icon: "mdi-radioactive-off", to: "/dicom", visible: 1, },
{ title: "Estatísticas", icon: "mdi-chart-box", to: "", visible: 1,
items: [ { title: "Clientes", icon: "mdi-account-arrow-right", to: "", visible: 1,
items: [ { title: "Por convênios", icon: "mdi-poll", to: "/estat_cliente_por_convenios", visible: 1, },
{ title: "Por mês", icon: "mdi-poll", to: "/estat_cliente_por_mes", visible: 1, },
],
},
{ title: "Faturamento", icon: "mdi-cash-usd", to: "", visible: 1,
items: [ { title: "Por convênios", icon: "mdi-poll", to: "/estat_faturamento_por_convenios", visible: 1, },
{ title: "Por mês", icon: "mdi-poll", to: "/estat_faturamento_por_mes", visible: 1, },
], },
], },
{ title: "Autorizações", icon: "mdi-microphone-variant", to: "/listaautorizacoes", visible: 1, },
{ title: "Faturamento", icon: "mdi-cash-usd", to: "", visible: 1,
items: [ { title: "Nova Guia", icon: "mdi-cart-plus", to: "/guiasfaturas", visible: 0, },
{ title: "Lista Guias", icon: "mdi-tray-plus", to: "/listaguias", visible: 1, },
{ title: "Lote de Guias", icon: "mdi-bag-personal", to: "/loteguias", visible: 1, }, ], },
]
function ofilter(arr) {
var matches = [];
if (!Array.isArray(arr)) return matches;
arr.forEach(function(i) {
if (i.visible && i.visible === 1) {
matches.push(i);
} else {
let childResults = this.ofilter(i.items);
if (childResults.length)
matches.push(Object.assign({}, i, {
items: childResults
}));
}
});
return matches;
}
console.log(ofilter(items))
Here's a recursive filter based on a recursive visibility check. This version preserves the nested structure:
const isVisible = item => item.visible
|| item.items?.some(isVisible)
const filterItems = items => {
items.forEach(item => {
if (item.items) item.items = filterItems(item.items)
})
return items.filter(isVisible)
}
console.log(filterItems(
[
{ id: 'a', visible: 1 },
{ id: 'b', visible: 0 },
{
id: 'c',
visible: 0,
items: [
{ id: 'd', visible: 1 },
{ id: 'e', visible: 0 }
]
},
{ id: 'f', visible: 1, items: [{ id: 'g', visible: 0 }] },
{ id: 'h', visible: 0, items: [{ id: 'i', visible: 0 }] },
]
))
Alternatively, here's a version that returns a flat array:
const filterItemsFlat = (items, results = []) => {
items.forEach(item => {
if (item.items) filterItemsFlat(item.items, results)
if (item.visible) results.push(item)
})
results.forEach(r => delete r.items)
return results
}
console.log(filterItemsFlat(
[
{ id: 'a', visible: 1 },
{ id: 'b', visible: 0 },
{
id: 'c',
visible: 0,
items: [
{ id: 'd', visible: 1 },
{ id: 'e', visible: 0 }
]
},
{ id: 'f', visible: 1, items: [{ id: 'g', visible: 0 }] },
{ id: 'h', visible: 0, items: [{ id: 'i', visible: 0 }] },
]
))
Another alternative to question:
const items = [
{ icon: "mdi-view-dashboard", title: "Dashboard", to: "/", visible: 1, },
{ title: "Manutenção", icon: "mdi-hammer-screwdriver", to: "", visible: 0,
items: [
{ title: "Usuários", icon: "mdi-account", to: "/usuarios", visible: 1, },
{ title: "Cores", to: "", visible: 0}
]
}
];
function ofilter(arr) {
let r = [];
arr.forEach((i) => {
if (i.visible == 1) {
r.push(i);
}
if (i.items) {
r.push(ofilter(i.items))
}
})
return r;
}
console.log('result:', ofilter(items))
I'm currently working on an Angular application and want to iterate over an array of objects that have nested data. I want to mutate the existing array when a user clicks a checkbox changing the checked property from false to true and vise Versa. For simplicity sake, I'm only posting the array structure.
I tried
const checklistCashe = [
{
categories: [
{
title: "Administrators",
items: [
{subTitle: "Admin", checked: false},
{subTitle: "Associates", checked: false},
{subTitle: "Hr", checked: false},
]
},
{
title: "Associates",
items: [
{subTitle: "Admin", checked: false},
{subTitle: "Associates", checked: false},
{subTitle: "Hr", checked: false},
{subTitle: "Users", checked: false},
]
},
{
title: "Organization",
items: [
{subTitle: "Contract", checked: false},
{subTitle: "External", checked: false},
{subTitle: "Internal", checked: false},
]
},
{
title: "Products",
items: [
{subTitle: "Concept", checked: false},
{subTitle: "Demo", checked: false},
{subTitle: "Production", checked: false},
]
},
{
title: "Reporting",
items: [
{subTitle: "Admin", checked: false},
{subTitle: "Associates", checked: false},
{subTitle: "Hr", checked: false},
]
}
]
}
]
const category = "Reporting";
const subCategory = "Admin";
I want to mutate the current array based on the category and subCategory provided. So I only want the checked property to change if the title is Reporting and the subTitle is Admin.
{
title: "Reporting",
items: [
{subTitle: "Admin", checked: true},
{subTitle: "Associates", checked: false},
{subTitle: "Hr", checked: false},
]
}
The best way with what you have would be something like:
function toggleChecked(title, subtitle) {
checklistCashe[0].categories.forEach((category) => {
if (category.title === title) {
category.items.forEach((item) => {
if (item.subTitle === subtitle) {
item.checked = !item.checked;
}
});
}
});
}
However, I feel like you might be better off formatting your checklistCashe to something more like:
const checklistCashe = {
Administrators: {
Admin: false,
Associates: false,
Hr: false
}
[...]
}
Then you can do something more like:
function toggleChecked(title, subtitle) {
checklistCashe[title][subtitle] = !checklistCashe[title][subtitle]
}
and you wouldn't have to iterate.
If you wanna keep it clean then use lodash as shown below
const checkListCache = [
{
categories: [
{
title: 'Administrators',
items: [
{ subTitle: 'Admin', checked: false },
{ subTitle: 'Associates', checked: false },
{ subTitle: 'Hr', checked: false },
],
},
{
title: 'Associates',
items: [
{ subTitle: 'Admin', checked: false },
{ subTitle: 'Associates', checked: false },
{ subTitle: 'Hr', checked: false },
{ subTitle: 'Users', checked: false },
],
},
{
title: 'Organization',
items: [
{ subTitle: 'Contract', checked: false },
{ subTitle: 'External', checked: false },
{ subTitle: 'Internal', checked: false },
],
},
{
title: 'Products',
items: [
{ subTitle: 'Concept', checked: false },
{ subTitle: 'Demo', checked: false },
{ subTitle: 'Production', checked: false },
],
},
{
title: 'Reporting',
items: [
{ subTitle: 'Admin', checked: false },
{ subTitle: 'Associates', checked: false },
{ subTitle: 'Hr', checked: false },
],
},
],
},
];
const category = 'Reporting';
const subCategory = 'Admin';
const { categories } = checkListCache[0];
const selectedCategory = _.find(categories, ['title', category]);
const selectedSubCategory = _.find(selectedCategory.items, ['subTitle', subCategory]);
selectedSubCategory.checked = !selectedSubCategory.checked;
console.log(checkListCache);
You can add safety checks as well before each loop to ensure we have values before manipulating it.
Use nested map calls:
function mutate (arr)
{
return arr.map(innerArr =>
{
return {
title: innerArr.title,
items: innerArr.items.map(item => {
return {
subTitle: item.subTitle,
checked: (innerArr.title === "Reporting" && item.subTitle === "Admin") ? false : item.checked,
};
}),
};
});
}
I have a jqGrid that loads fine and the drop down loads fine as well but I'm not sure hot to go about updating(loading) the second dropdown based on the first dropdown's onchange event.
Here is my grid. As you can see I load countries but now I would like to load the available currencies based on the selected country.
$("#jqgrid").jqGrid
({
url: '#Url.Action("GetSupplierData", "Maintenance")',
datatype: 'json',
mtype: 'Get',
//table header name
colNames: [
'Id', 'Code', 'Name', 'Account Number', 'Contact Person', 'Contact Number',
'Email', 'Address', 'Country', 'Currency', 'InsertUserId',
'InsertDateTime', 'InsertUserName', 'UpdateUserId', 'UpdateDateTime', 'UpdateUserName'
],
//colModel takes the data from controller and binds to grid
colModel: [
{
key: true,
hidden: true,
name: 'id',
index: 'id',
editable: true
}, {
key: false,
name: 'code',
index: 'code',
editable: true
}, {
key: false,
name: 'name',
index: 'name',
editable: true
}, {
key: false,
name: 'accountnumber',
index: 'accountnumber',
editable: true
}, {
key: false,
name: 'contactperson',
index: 'contactperson',
editable: true
}, {
key: false,
name: 'contactnumber',
index: 'contactnumber',
editable: true
}, {
key: false,
name: 'email',
index: 'email',
editable: true
}, {
key: false,
name: 'address',
index: 'address',
editable: true
}, {
key: false,
name: 'countryId',
index: 'countryId',
editable: true,
edittype: 'select',
editoptions: {
dataInit: function(element) {
$.ajax({
url: '#Url.Action("GetCountries", "Maintenance")',
dataType: 'json',
type: 'POST',
success: function(response) {
var array = response;
if (array != null) {
var i;
for (i in array) {
if (array.hasOwnProperty(i)) {
if (ctyId == array[i].id) {
$(element).append("<option value=" + array[i].id +" selected>" + array[i].name +"</option>");
} else {
$(element).append("<option value=" + array[i].id + ">" + array[i].name + "</option>");
}
}
}
}
}
});
},
dataEvents:
{
type: 'change',
fn: function (e) {
}
}
},
editrules: { required: true, integer: true }
}, {
key: false,
name: 'currencyId',
index: 'currencyId',
editable: true
}, {
key: false,
hidden: true,
name: 'insertUserId',
index: 'insertUserId',
editable: true
}, {
key: false,
hidden: true,
name: 'insertDateTime',
index: 'insertDateTime',
editable: true
}, {
key: false,
hidden: true,
name: 'insertUserName',
index: 'insertUserName',
editable: true
}, {
key: false,
hidden: true,
name: 'updateUserId',
index: 'updateUserId',
editable: true
}, {
key: false,
hidden: true,
name: 'updateDateTime',
index: 'updateDateTime',
editable: true
}, {
key: false,
hidden: true,
name: 'updateUserName',
index: 'updateUserName',
editable: true
}
],
rowNum: 10,
rowList: [10, 20, 30, 40],
height: '100%',
caption: 'Suppliers',
emptyrecords: 'No records to display',
jsonReader:
{
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
Id: "0"
},
pager: '#pjqgrid',
sortname: 'id',
toolbarfilter: true,
viewrecords: true,
sortorder: "asc",
autowidth: true,
multiselect: false,
onSelectRow: function(id) {
var selRowId = $("#jqgrid").jqGrid('getGridParam', 'selrow');
ctyId = $("#jqgrid").jqGrid('getCell', selRowId, 'currencyId');
}
//pager-you have to choose here what icons should appear at the bottom
//like edit,create,delete icons
}).navGrid('#pjqgrid',
{
edit: true,
add: false,
del: true,
search: true,
refresh: true
},
{
// edit options
zIndex: 1000,
url: '#Url.Action("EditSupplier", "Maintenance")',
dataType: "html",
closeOnEscape: true,
closeAfterEdit: true,
recreateForm: true,
afterComplete: function(response) {
$('#alerts').html(response.responseText);
}
},
{
// add options
},
{
// delete options
zIndex: 1000,
url: '#Url.Action("DeleteSupplier", "Maintenance")',
type: "POST",
closeOnEscape: true,
closeAfterDelete: true,
recreateForm: true,
msg: "Are you sure you want to delete this?",
afterComplete: function(response) {
$('#alerts').html(response.responseText);
}
});
This Guriddo of jqGrid example will point you in the right direction.