Find match in two arrays - arrays

Update
Got the answer:
if (this.checkedColors.length > 0) {
straps = straps.filter(strap => {
return strap.colors.find(color => {
return this.checkedColors.includes(color.title.toLowerCase());
});
});
}
I have two arrays, where I need to return products that match the checkbox value.
I've created a screen recording to display how this works: http://recordit.co/EddLjeqM7i
My code is the following:
export default {
data() {
checkedColors: [],
filterings: [{
title: "Farver",
filters: [{
title: "Grøn",
value: "grøn"
},
{
title: "Rød",
value: "rød"
},
{
title: "Gul",
value: "yellow"
},
{
title: "Lilla",
value: "lilla"
},
{
title: "Blå",
value: "blå"
},
{
title: "Grå",
value: "grå"
},
{
title: "Sort",
value: "sort"
},
{
title: "Hvid",
value: "hvid"
},
{
title: "Brun",
value: "brun"
}
]
}
}
},
computed: {
filteredStraps() {
var straps = this.straps;
if (this.search !== null) {
var straps = this.searchItems.filter(strap => {
if (!this.search) return this.searchItems;
return (
strap.title.toLowerCase().includes(this.search.toLowerCase()) ||
strap.skin.toLowerCase().includes(this.search.toLowerCase()) ||
strap.type.toLowerCase().includes(this.search.toLowerCase())
);
});
}
if (this.checkedSkins.length > 0) {
straps = straps.filter(strap => {
return this.checkedSkins.includes(strap.skin.toLowerCase());
});
}
if (this.checkedTypes.length > 0) {
straps = straps.filter(strap => {
return this.checkedTypes.includes(strap.type.toLowerCase());
});
}
if (this.checkedColors.length > 0) {
straps = straps.filter(strap => {
return this.checkedColors.includes(strap.colors.toLowerCase());
});
}
if (this.sort == "newest") {
return straps.sort((a, b) => new Date(a.date) - new Date(b.date));
}
if (this.sort == "priceasc") {
return straps.sort((a, b) => a.price > b.price);
}
if (this.sort == "pricedesc") {
return straps.sort((a, b) => a.price < b.price);
} else {
return straps;
}
}
},
<v-expansion-panel class="elevation-0">
<v-expansion-panel-content v-for="filtering in filterings.slice(0, 1)" :key="filtering.title">
<div slot="header">{{filtering.title | capitalize}}</div>
<v-card>
<v-card-text>
<v-list>
<v-list-tile v-for="filter in filtering.filters" :key="filter.value">
<v-list-tile-content>
<v-checkbox :value="filter.value" :label="filter.title" v-model="checkedColors" color="primary"></v-checkbox>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-card-text>
</v-card>
</v-expansion-panel-content>
</v-expansion-panel>
The straps array is the following: https://i.imgur.com/HIEBgqW.png
I'll need the function to be computed in order to match the other filtering and sorting methods, to return the straps correctly.
I have two other methods that are working, but they didn't require looping through an array to find a match for the value or values I'm looking for.

Related

Full row editing with custom select editor and dynamic options updating

I am trying to implement a custom select editor with dynamic options updating in ag-grid.
Saw an example of the same in vue js
AG Grid Vue example
How can to render the dynamic options in table cell?
//custom dropdown for cell editor
export const CustomDropDownEditor = forwardRef((props: any, ref) => {
const createInitialState = () => {
let startValue = props.value;
const filter = props?.values?.filter((item) => item.isSelected);
if (filter?.length) {
startValue = filter[0].dataFieldLookupId;
} else {
startValue = -1;
}
return {
value: startValue,
};
};
const [value, setValue] = useState(-1);
const refSelect = useRef<HTMLSelectElement>(null);
const dispatch = useDispatch<any>();
useEffect(() => {
if (props?.values?.length) {
const state: any = createInitialState();
setValue(state.value);
}
}, [props]);
useImperativeHandle(ref, () => {
return {
getValue() {
return value;
},
isCancelBeforeStart() {
},
isCancelAfterEnd() {
},
};
});
const onselectionchange = (e) => {console.log(props)
if (props?.properties?.dataFieldRelation) {
let service: any = props?.properties?.dataFieldRelation?.subSetValueService;
if (service !== undefined) {
service = service.replace("{dataFieldLookupId}", e?.target?.value);
dispatch(getDatafieldValues(service, props?.properties?.dataFieldRelation?.childDataFieldId, props.body))
}
const index = props?.datafields?.findIndex((item) => item?.uniqueDataFieldId == props?.properties?.uniqueDataFieldId);
props?.datafields[index]?.validatedValues?.forEach(element => {
if (element?.dataFieldLookupId == e.target.value)
element.isSelected = true;
else
element.isSelected = false;
});
props?.setFields(props?.datafields);
} else {
if (props?.properties?.dataFieldName === "Test Method") {
} else if (props?.properties?.dataFieldName === "Test Result") {
} else {
const index = props?.datafields?.findIndex((item) => item?.uniqueDataFieldId == props?.properties?.uniqueDataFieldId);
props?.datafields[index]?.validatedValues?.forEach(element => {
if (element?.dataFieldLookupId == e.target.value)
element.isSelected = true;
else
element.isSelected = false;
});
props?.setFields(props?.datafields);
}
}
setValue(e.target.value);
}
return (
<select
ref={refSelect}
name={props.properties.uniqueDataFieldId}
id={props.properties.uniqueDataFieldId}
value={value}
onChange={onselectionchange}>
<option value={-1}>--Select--</option>
{props?.values?.map((item, key) => (
<option key={key} value={item.dataFieldLookupId}>{item.dataFieldLookupValue}</option>
))
}
</select>
)
})
//get column definition in dynamically
const getEquipmentColumn = (generalProperties, datafields, isEditMode) => {
const columnInfo: any = [];
if (generalProperties?.length) {
for (var i = 0; i < generalProperties?.length; i++) {
if (generalProperties[i]?.name === "EquipmentId") {
let data: any = {
headerName: "action",
minWidth: 150,
cellRenderer: EditButtom,
editable: false,
colId: "action",
pinned: "left",
lockPinned: true
}
columnInfo.push(data);
}
if (generalProperties[i]?.propertyType !== "INTERNAL") {
let data: any = {
headerName: generalProperties[i]?.alias,
field: generalProperties[i]?.name,
comparator: comparator,
}
if (datafields?.length && isEditMode) {
const filterData = datafields?.filter((item) => item?.uniqueDataFieldId === generalProperties[i]?.uniqueDataFieldId);
if (filterData?.length) {
if (["Text Box", "Text Area"].includes(filterData[0]?.dataEntryControl?.dataEntryControlName)) {
if (filterData[0].disabled === false) {
data.editable = true;
data.cellEditor = "customeTextBox"
data.cellEditorParams = {
properties: filterData[0],
datafields: datafields,
}
} else {
data.editable = false;
}
}
else if (filterData[0]?.dataEntryControl?.dataEntryControlName === "Date Picker") {
data.editable = false;
} else if (filterData[0]?.dataEntryControl?.dataEntryControlName === "Date Time Picker") {
data.editable = false;
} else if (filterData[0]?.dataEntryControl?.dataEntryControlName === "Drop-down list") {
if (filterData[0].disabled === false) {
data.editable = true;
data.cellEditor = "customDropDown"
data.cellEditorParams = {
values: filterData[0].validatedValues,
properties: filterData[0],
datafields: datafields,
body: body,
setFields: (props) => setDatafields([...props]),
}
} else {
data.editable = false;
}
}
} else {
data.editable = false;
}
}
columnInfo.push(data);
}
}
}
return [columnInfo, isEditMode];
}
//getting additional values for dependency dropdown
useLayoutEffect(() => {
if (additionalFieldValues) {
let fieldValues = JSON.parse(JSON.stringify(additionalFieldValues));
const findIndex = datafields?.findIndex((item) => item.uniqueDataFieldId === fieldValues[1]);
if (findIndex >= 0) {
datafields[findIndex].validatedValues = fieldValues[0];
}
agGridRef.current.api.refreshCells({ columns: [`${datafields[findIndex].dataFieldName}`], force: true });
setDatafields(datafields);
dispatch(setAdditionalDatafieldValues(""));
}
}, [additionalFieldValues])

Map Data Based off ID

If i'm using the map function, how would you limit it by ID, e.g I only want to map ID 1,2 out of 3 possible datapoints?
What's the industry standard solution?
export const userInputs = [
{
id: 1,
label: "First Name",
type: "text",
placeholder: "Remy",
},
{
id: 2,
label: "Surname",
type: "text",
placeholder: "Sharp",
},
{
id: 3,
label: "Email",
type: "email",
placeholder: "remysharp#gmail.com",
}
];
Mapping like this, for email, i'd only like name and surname to be mapped inputs.
{inputs.map((input) => (
<FormInput className="formInput" key={input.id}>
<UserInput type={input.type} placeholder={input.placeholder} />
</FormInput>
))}
Use for loop.
function SomeComponent() {
const useInputs = [
/*...*/
]
const limit = 2
const userInputDomList = []
for (let i = 0; i < userInputs.length; i++) {
if (limit >= i) break
userInputDomList.push(<div key={userInputs[i].id}> </div>)
}
return <section>{userInputDomList}</section>
}
you could use .filter or .map for same result but it will loop over all elements instead of stopping at limit index.
For id based selection
function SomeComponent() {
const useInputs = [
/*...*/
]
const userInputDomList = []
// using for loop
/* for (let i = 0; i < userInputs.length; i++) {
const id = userInputs[i].id
if (id === 3) {
userInputDomList.push(<div key={id}> </div>)
break
}
} */
// using for..of
for (const userInput of userInputs) {
if (userInput.id === 3) {
userInputDomList.push(<div key={userInput.id}> </div>)
break
}
}
return <section>{userInputDomList}</section>
}
if really want reander only one item to be rendered
function RenderMatchingId({ userInputs, userInputId }) {
for (const userInput of userInputs) {
if (userInput.id === userInputId) {
return <section>found {userInput.id}</section>
}
}
// fallback
return <section>404 not found</section>
}

Push value of arrivalDate in array

I would like to store every arrivalDate in my array list.
Someone could tell me how can I do it?
But my array is still empty.
JSON returned by the API:
{
"reservations": {
"reservationInfo": [
{
"roomStay": {
"arrivalDate": "11am"
},
"WeatherR": {
"sound": "cloudy"
},
},
{
"roomStay": {
"arrivalDate": "7pm"
},
"WeatherR": {
"sound": "cloudy"
},
}
]
}
}
component.ts
searchForReservation() {
alert('hello');
this.http.get('/api/searchForReservation')
.subscribe((data) => {
this.ddataIno = data;
this.ddataIno = this.ddataIno.result.reservations.reservationInfo;
console.log('number of value', this.ddataIno.length);
console.log('content', this.ddataIno);
for (let i = 0; i <= this.ddataIno[i].length; i++) {
this.list = this.ddataIno.roomStay.arrivalDate;
}
console.log('store array', this.list)
})
}
searchForReservation() {
alert('hello');
this.http.get('/api/searchForReservation')
.subscribe((data) => {
const reservationInfo = this.data.result.reservations.reservationInfo;
this.list = reservationInfo.map(e => e.roomStay.arrivalDate);
})
}
Here's a working example in vanilla JS. You would need to make some small adjustments for angular, like this.list = ... instead of let list = ...
Using Array#map, you can create a new array from the JSON object
data.reservations.reservationInfo.map(r => r.roomStay.arrivalDate)
let data = {
"reservations": {
"reservationInfo": [{
"roomStay": {
"arrivalDate": "11am"
},
"WeatherR": {
"sound": "cloudy"
},
},
{
"roomStay": {
"arrivalDate": "7pm"
},
"WeatherR": {
"sound": "cloudy"
},
}
]
}
}
// declare your list as an array at the top
// list: []
// below would start off as 'this.list'
let list = data.reservations.reservationInfo.map(r => r.roomStay.arrivalDate);
console.log(list);
Your for loop is just reassigning the value of this.list
I suggest reading up on Array methods
I would use a map method, e.g.
this.list = this.ddataIno.result.reservations.reservationInfo.map(i => i.roomStay.arrivaldate);

Reducing nested array

I am receiving this JSON from my backend and i need to work out the count of "concrete_compressive_cylinder_100"'s where picked_up = false
concrete_samples (can be multiple per work order) can be null ( key is always present )
sample_specimens ( 1 per concrete_sample) can be null ( key is always present )
concrete_compressive_cylinder_100 ( null to 500 per sample_specimens )
{
"uuid":"4ad7bfe1-48d6-488c-bfaf-33f7189a41d7",
"org_workorder_id":1000,
"concrete_samples":[
{
"uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b",
"workorder_uuid":"4ad7bfe1-48d6-488c-bfaf-33f7189a41d7",
"org_sample_id":5001,
"sample_specimens":{
"concrete_compressive_cylinder_100":[
{
"uuid":"b9ef3a8a-2945-41e6-a34d-d90d1bd64819",
"sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b",
"picked_up":true
},
{
"uuid":"d43f15b3-2208-43de-8fff-8d237c6918f9",
"sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b",
"picked_up":true
},
{
"uuid":"472f832a-6f07-4af6-97ea-e6dc7b9b3799",
"sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b",
"picked_up":true
}
],
"concrete_compressive_cylinder_200":[
{
"uuid":"d659d058-e4ec-4f72-9d73-9ea98295715a",
"sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b",
"picked_up":true
},
{
"uuid":"777372e0-3e58-4292-bae4-bec84dfe1402",
"sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b",
"picked_up":true
},
{
"uuid":"f63f7102-7673-4e71-97e5-2d85e0c1a93d",
"sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b",
"picked_up":true
}
]
}
},
{
"uuid":"61138cf3-0c49-4495-8a89-533c0a6e50bc",
"workorder_uuid":"4ad7bfe1-48d6-488c-bfaf-33f7189a41d7",
"org_sample_id":5002,
"sample_specimens":{
"concrete_compressive_cylinder_100":null,
"concrete_compressive_cylinder_200":null
}
}
]
}
I've gotten this far but it dosen't really work and now im more confused some guidance would be great
const out = res.data.concrete_samples.reduce((acc, sample) => {
const { sample_specimens } = sample;
const concrete_compressive_cylinder_100 = Object.keys(sample_specimens)["concrete_compressive_cylinder_100"];
const specimens = concrete_compressive_cylinder_100.map(obj => {
obj.picked_up ? console.log("picked up") : console.log("Not pickedn up")
});
}, []);
Array.prototype.reduce accepts a function whose return value is eventually returned from reduce itself. The function is passed each element of the array, along with the value accumulated so far. For example,
[1, 2, 3].reduce((accumulator, element) => accumulator + element)
// => 6
You can also provide an initial value, which will be passed to your function as accumulator on the first iteration.
At a basic level, to count how many occurrences of an object with a certain property with reduce, you could use something like this,
let array = [
{ foo: 4 },
{ foo: 6 },
{ bar: 8 },
]
array.reduce((count, element) => {
if (element.foo !== undefined) {
return count + 1
} else {
return count
}
}, 0)
// => 2
Extending this to your code (with extraneous data elided), with a nested reduce to get the count of cylinders with the desired picked_up property,
const data = {
"concrete_samples":[
{
"sample_specimens":{
"concrete_compressive_cylinder_100":[
{
"picked_up":true
},
{
"picked_up":true
},
{
"picked_up":true
}
],
"concrete_compressive_cylinder_200":[
{
"picked_up":true
},
{
"picked_up":true
},
{
"picked_up":true
}
]
}
},
{
"sample_specimens":{
"concrete_compressive_cylinder_100":null,
"concrete_compressive_cylinder_200":null
}
}
]
}
const result = data.concrete_samples.reduce((count, sample) => {
const cylinders = sample.sample_specimens.concrete_compressive_cylinder_100
if (cylinders == null) {
return count
}
const samplePickedUpCount = cylinders.reduce((pickedUpCount, cylinder) => {
if (cylinder.picked_up) {
return pickedUpCount + 1
} else {
return pickedUpCount
}
}, 0)
return count + samplePickedUpCount
}, 0)
console.log(result)
You could also use Array.prototype.filter to accomplish the same thing, getting an array of the cylinders with the desired property, and getting the length of that array.
If I understand correctly, you'd like to obtain a new concrete_samples array where the array values of nested sample_specimens objects are reduced to the number of items where picked_up is true - one approach to that would be as documented in the following snippet:
const data={"uuid":"4ad7bfe1-48d6-488c-bfaf-33f7189a41d7","org_workorder_id":1000,"concrete_samples":[{"uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b","workorder_uuid":"4ad7bfe1-48d6-488c-bfaf-33f7189a41d7","org_sample_id":5001,"sample_specimens":{"concrete_compressive_cylinder_100":[{"uuid":"b9ef3a8a-2945-41e6-a34d-d90d1bd64819","sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b","picked_up":true},{"uuid":"d43f15b3-2208-43de-8fff-8d237c6918f9","sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b","picked_up":true},{"uuid":"472f832a-6f07-4af6-97ea-e6dc7b9b3799","sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b","picked_up":true}],"concrete_compressive_cylinder_200":[{"uuid":"d659d058-e4ec-4f72-9d73-9ea98295715a","sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b","picked_up":true},{"uuid":"777372e0-3e58-4292-bae4-bec84dfe1402","sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b","picked_up":true},{"uuid":"f63f7102-7673-4e71-97e5-2d85e0c1a93d","sample_uuid":"776a8ccb-82fd-4a42-a6eb-8f286a4a9c0b","picked_up":true}]}},{"uuid":"61138cf3-0c49-4495-8a89-533c0a6e50bc","workorder_uuid":"4ad7bfe1-48d6-488c-bfaf-33f7189a41d7","org_sample_id":5002,"sample_specimens":{"concrete_compressive_cylinder_100":null,"concrete_compressive_cylinder_200":null}}]};
const concreteSamplesResult = data.concrete_samples.map(sample => {
// Iterate each key/value entry of sample_specimens, and reduce to a new
// specimens object that contains counts of picked_up: true items in sub array
const sample_specimens = Object
.entries(sample.sample_specimens)
.reduce((specimens, entry) => {
// Calculate count of picked_up items for arr of this entry
const [key, arr] = entry;
const count = Array.isArray(arr) ?
arr.reduce((total, item) => (total + (item.picked_up ? 1 : 0)), 0) : 0;
// Add count for entry key to newly reduced sample_specimen object
return { ...specimens, [key] : count };
},{})
return { ...sample, sample_specimens };
});
console.log(concreteSamplesResult);
Check null > loop > check null > loop and count isn't it?
function someFunc(json) {
const { concrete_samples } = json;
if (!concrete_samples) return;
let numberOFAvailableCylinder100s = 0;
const doSomethingWithCylinder = cylinder => {
console.log(cylinder.uuid);
numberOFAvailableCylinder100s += 1;
}
concrete_samples.forEach(concrete_sample => {
const { sample_specimens } = concrete_sample;
if (!sample_specimens) return;
findAvailableCylinder100(sample_specimens, doSomethingWithCylinder);
})
console.log(`count: ${numberOFAvailableCylinder100s}`);
}
function findAvailableCylinder100(sample_specimens, callback) {
const { concrete_compressive_cylinder_100 } = sample_specimens;
if (!concrete_compressive_cylinder_100) return;
concrete_compressive_cylinder_100.forEach(cylinder => {
if (!cylinder.picked_up) callback(cylinder);
});
}
someFunc(yourJSONObject);

How can I manipulate a 2D array in React?

i tried to save list of equipments in arrays.
i need to add quantity for each equipemnt so i have to transform the one dimensional to two dimensional
how can i change this todeclare in state arrays as 2D?
this.state = {
equipments: [{
number: ''
},{
number: ''
}]};
and how to setsate ?
handleSubmit(event) {
const orderData = {
equipments: this.state.equipments.map(equipment => {
return {equipemnt: equipment.number}
})
};
createOrder(orderData);
}
validateEquipment = (equipmentNumber) => {
if(equipmentNumber.length === 0) {
return {
validateStatus: 'error',
errorMsg: 'Please enter a choice!'
}
} else if (equipmentNumber.length > 50) {
return {
validateStatus: 'error',
errorMsg: `Choice is too long (Maximum 50 characters allowed)`
}
} else {
return {
validateStatus: 'success',
errorMsg: null
}
}
}
handleEquipmentChange(event, index) {
const equipments = this.state.equipments.slice();
const value = event.target.value;
equipments[index] = {
number: value,
...this.validateEquipment(value)
}
this.setState({
equipments: equipments
});
}
it would be easier if you use object instead of array
this.state = {
equipments: {
eq1: { qty: 0 },
eq2: { qty: 0 }
}
}
adding / updating new equipment would be as simple as:
addOrUpdateQty(id, qty) {
this.setState({ equipments: {...this.state.equipments, [id]: { qty }} })
}

Resources