I have some code that is using conditional chaining such as
productQuantity = purchases.filter((pObj) => pObj.elements[0]?.prodType?.id === purchase.elements[0]?.prodType?.id && pObj.sold === purchase.sold).length
It works fine but I need to convert the chained conditionals to an older method and I'm not sure how. Can anyone advise ?
Reason being that PM2 does not support chaining conditional operators.
Let's try this. Replacing all key?.key2 with key && key.key2
productQuantity = purchases.filter((pObj) => {
return pObj.elements[0] && pObj.elements[0].prodType && purchase.elements[0] && purchase.elements[0].prodType && pObj.elements[0].prodType.id === purchase.elements[0].prodType.id && pObj.sold === purchase.sold
}).length
I would probably do something like this.
First, we make the observation that the we are selecting an id from two similar objects: we can therefore refactor the logic required to select the id into a common function:
function selectId(item) {
if (item) {
const elements = item.elements;
if (elements) {
const element = elements[0];
if (element) {
const prodType = element.prodType;
if (prodType) {
const id = prodType.id;
return id;
}
}
}
}
}
You could also flatten the selection (which may or may not be more readable/maintainable):
function selectId(item) {
if (!item) return undefined;
const elements = item.elements;
if (!elements) return undefined;
const element = elements[0];
if (!element) return undefined;
const prodType = element.prodType;
if (!element) return undefined;
const id = prodType.id;
return id;
}
Once you have that, then your filter comes down to this:
productQuantity = purchases.filter( isMatch ).length;
function isMatch(obj) {
let itemId = selectId(obj);
let purchaseId = selectId(purchase);
const shouldKeep = itemId == purchaseId
&& obj.sold === purchase.sold;
return shouldKeep
}
Related
I've been trying to do some html and css but I'm really bad at this so far. I was using a function that would check if two selectors match. A friend of mine came up with this code but neither of us fully understands how the return of the "tag.class" case works. My question is, if it doesn't divide the newSelector, how can it succesfully check the tag and class?
var matchFunctionMaker = function(selector) {
var selectorType = selectorTypeMatcher(selector);
var matchFunction;
if (selectorType === "id") {
matchFunction = nuevoSelector => '#' + nuevoSelector.id === selector;
} else if (selectorType === "class") {
matchFunction = nuevoSelector => {
var lista = nuevoSelector.classList;
for (let x of lista) {
if (selector === '.' + x) return true;
}
return false;
}
} else if (selectorType === "tag.class") {
matchFunction = nuevoSelector => {
var [tag, clase] = selector.split('.');
return matchFunctionMaker(tag) (nuevoSelector) && matchFunctionMaker(`.${clase}`) (nuevoSelector);
};
} else if (selectorType === "tag") {
matchFunction = nuevoSelector => nuevoSelector.tagName.toLowerCase() === selector.toLowerCase();
}
return matchFunction;
};
Thanks in advance!
const filteredOptions = _.filter(grantedValuesFinal, o => o.numberOfShareOptionAwardGranted > 0);
let filteredArray = [];
filteredOptions.forEach(function(item, i){
let existing = filteredArray.filter(function(o, i) {
const dateNew = luxon.DateTime.fromISO(o.grantDate);
const dateExsisting = luxon.DateTime.fromISO(item.grantDate);
return o.grantDate == item.grantDate;
});
if (existing.length) {
let existingIndex = filteredArray.indexOf(existing[0]);
if(item.typeOfEquity == "Shares") filteredArray[existingIndex].numberOfShareOptionAwardGrantedShares += item.numberOfShareOptionAwardGranted;
if(item.typeOfEquity == "Options") filteredArray[existingIndex].numberOfShareOptionAwardGrantedOptions += item.numberOfShareOptionAwardGranted;
} else {
let numberOfShareOptionAwardGrantedShares = 0, numberOfShareOptionAwardGrantedOptions = 0;
if(item.typeOfEquity == "Shares") numberOfShareOptionAwardGrantedShares += item.numberOfShareOptionAwardGranted;
if(item.typeOfEquity == "Options") numberOfShareOptionAwardGrantedOptions += item.numberOfShareOptionAwardGranted;
filteredArray.push({grantDate: item.grantDate, numberOfShareOptionAwardGrantedShares: numberOfShareOptionAwardGrantedShares, numberOfShareOptionAwardGrantedOptions: numberOfShareOptionAwardGrantedOptions });
}
})
The very first line of the code does not pass any value, due to which filteredOptions and array is empty. What changes has to be done ? Please help
The filteredOptions array always stayed NULL as the grantedValuesFinal was only filtering out NULL values.
I was able to work out the code by placing !=NULL and got the non-null values.
Thank you all for your insights
I have a filtering system where I use an array to add or remove the filtering methods. But my state is not working properly or i've missed something.
const [filters, setFilters] = useState([]);
const [creatorFilter, setCreatorFilter] = useState(null);
const handleCreatorFilter =(filter) => {
setCreatorFilter(filter);
if (filter === 'structures' && filters.indexOf(byStructureFilter) === -1) {
setFilters([...filters, byStructureFilter]);
}
if (filter === 'members' && filters.indexOf(byMemberFilter) === -1) {
setFilters([...filters, byMemberFilter]);
}
if (filter === 'all') {
setFilters(filters.filter(el => el !== byStructureFilter || el !== byMemberFilter));
}
};
const byStructureFilter = (item) => {
return item.relationships.structure.data
};
const byMemberFilter = (item) => {
return item.relationships.user.data && !item.relationships.structure.data
};
Here the two buttons calling that handleCreatorFilter for filtering
<button onClick={() => creatorFilter === 'structures' ? handleCreatorFilter('all') : handleCreatorFilter('structures')}>Structures officielles</button>
<button onClick={() => creatorFilter === 'members' ? handleCreatorFilter('all') : handleCreatorFilter('members')} >Membres Wekomkom</button>
The things is for adding filtering methods to the array it works fine but not when the filter is set to all (removing the filtering methods). Do you see something wrong in my logic ?
Working on a project that is taking in 5 similar SQL databases, and I need to detect and filter out duplicates. I think I'm on the right track, but I'm not quite there yet. I am attempting to follow these steps to accomplish this:
start a .forEach() for the main array passing in an item object.
create a filtered array via let filtered = Array.filter(x => x.id !== item.id); to keep from checking against itself.
start a .forEach() for the filtered array passing in comparison as the parameter.
initialize variables for similarity in Name, Phone, and Email fields.(i.e.nameSimilarity, phoneSimilarity, and emailSimilarity)
If item.email and comparison.email aren't empty, compare the strings and store the similarity percentage in emailSimilarity else emailSimilarity=0.
If item.phone and comparison.phone aren't empty, compare the strings and store the similarity percentage in phoneSimilarity else phoneSimilarity=0.
Combine item.firstName and item.lastName into an variable called itemFullName and combine comparison.firstName and comparison.lastName into a variable called comparisonFullName.
If itemFullName and comparisonFullName aren't empty, compare the strings and store the similarity percentage in nameSimilarity else nameSimilarity=0.
if any of the percentages in emailSimilarity, nameSimilarity, or phoneSimilarity, add item plus the similarity variables and comparison.id to the duplicates array, and splice it out of the original array.
This is the code that I've written to follow these steps, but it appears that I'm getting duplicate entries in the duplicates array. I'm not sure why it's not working as expected, but I have a hunch that I can't really expect the original array to mutate inside the forEach() operation.
fullArray.forEach(item => {
let filtered = fullArray.filter(x => x.externalId !== item.externalId);
filtered.forEach(comparison => {
let emailSimilarity, phoneSimilarity, nameSimilarity;
if ((item.email !== '') && (comparison.email !== '')) {
emailSimilarity = strcmp.jaro(item.email, comparison.email);
} else {
emailSimilarity = 0;
}
if ((item.phone !== '') && (comparison.phone !== '')) {
phoneSimilarity = strcmp.jaro(item.phone, comparison.phone);
} else {
phoneSimilarity = 0;
}
let itemFullName = `${item.firstName} ${item.LastName}`.trim() || '';
let comparisonFullName = `${comparison.firstName} ${comparison.LastName}`.trim();
if (((itemFullName !== '') && (comparisonFullName !== '')) || ((itemFullName.indexOf('Group')! > 0) && (comparisonFullName.indexOf('Group') !>0))) {
nameSimilarity = strcmp.jaro(itemFullName, comparisonFullName);
} else {
nameSimilarity = 0;
}
if ((emailSimilarity || phoneSimilarity || nameSimilarity) > 0.89) {
let dupesOutput = Object.assign({}, item, { similarName: nameSimilarity, similarEmail: emailSimilarity, similarPhone: phoneSimilarity, similarTo: comparison.externalId });
dupes.push(dupesOutput);
fullArray = fullArray.filter(x => x.externalId !== item.externalId);
}
});
});
Where's the issue?
Assuming the similarity check is working, the problem is that you're reassigning a new array to fullArray while still being in the forEach loop of the old one.
I'd suggest you use Array.filter:
var filteredArray = fullArray.filter(item => {
return !fullArray.some(comparison => {
if(comparison.externalId==item.externalId)
return false;
let emailSimilarity, phoneSimilarity, nameSimilarity;
if ((item.email !== '') && (comparison.email !== '')) {
emailSimilarity = strcmp.jaro(item.email, comparison.email);
} else {
emailSimilarity = 0;
}
if ((item.phone !== '') && (comparison.phone !== '')) {
phoneSimilarity = strcmp.jaro(item.phone, comparison.phone);
} else {
phoneSimilarity = 0;
}
let itemFullName = `${item.firstName} ${item.LastName}`.trim() || '';
let comparisonFullName = `${comparison.firstName} ${comparison.LastName}`.trim();
if (((itemFullName !== '') && (comparisonFullName !== '')) || ((itemFullName.indexOf('Group')! > 0) && (comparisonFullName.indexOf('Group') !>0))) {
nameSimilarity = strcmp.jaro(itemFullName, comparisonFullName);
} else {
nameSimilarity = 0;
}
if ((emailSimilarity || phoneSimilarity || nameSimilarity) > 0.89) {
let dupesOutput = Object.assign({}, item, { similarName: nameSimilarity, similarEmail: emailSimilarity, similarPhone: phoneSimilarity, similarTo: comparison.externalId });
dupes.push(dupesOutput);
return true;
}else
return false;
});
});
I am in a fix in this situation. If the user presses '1. ', i change the block to ordered block. Following is the code I do to change it:
_handleBeforeInput(str) {
if (str !== '.') {
return false;
}
const { editorState } = this.state;
const selection = editorState.getSelection();
const currentBlock = editorState.getCurrentContent()
.getBlockForKey(selection.getStartKey());
const blockLength = currentBlock.getLength();
if (blockLength === 1 && currentBlock.getText() === '1') {
this.onChange((utilFn.resetBlockType(editorState, 'ordered-list-item')));
return 'handled';
}
return 'not-handled';
}
However, once the user creates an ordered-list-item block, I want to set a limit on the block being created. I tried to use the answer from this question: [How to limit Max Length of Draft js, however I dont know how can i handle multiple handlers in handlebeforeInput.
I tried using switch case etc. but it wasnt helping.
Please help me with this issue if anyone has faced it. Thanks!
I realized my mistake... it is pretty straightforward with using multiple if-else, following is the adjusted code:
_handleBeforeInput(str) {
const { editorState } = this.state;
const selection = editorState.getSelection();
const currentBlock = editorState.getCurrentContent()
.getBlockForKey(selection.getStartKey());
const blockLength = currentBlock.getLength()
const currentContent = this.state.editorState.getCurrentContent();
const currentContentLength = currentContent.getPlainText('').length
if (currentContentLength > 10 - 1){
alert('you can type max ten characters');
return 'handled';
}else if (str !== '.') {
return 'not-handled';
}else if(str === '.'){
if (blockLength === 1 && currentBlock.getText() === '1') {
this.onChange((utilFn.resetBlockType(editorState, 'ordered-list-item')));
return 'handled';
}
}
return 'not-handled';
}