how to change the loop to become a map? - javascript

I haven't found a way to change for into a map, so my plan won't use for but want to use maps in each function of this function
variantDefault = (colorId, sizeId) => {
let selected = [];
let i = 0;
if (this.props.index === 0) {
for (i = 0; i < this.props.values.length; i++) {
if (this.props.values[i].id === colorId) {
selected = this.props.values[i];
}
}
}
if (this.props.index === 1) {
for (i = 0; i < this.props.values.length; i++) {
if (this.props.values[i].id === sizeId) {
selected = this.props.values[i];
}
}
}
console.log(selected);
return selected;
};

you can try this way
variantDefault = (colorId, sizeId) => {
let selected = [];
if (this.props.index === 0) {
this.props.values.map((data) => {
if(data.id === colorId){
selected.push(data)
}
})
}
if (this.props.index === 1) {
this.props.values.map((data) => {
if (data.id === sizeId) {
selected.push(data)
}
})
}
console.log(selected);
return selected;
};

You could take Array#find and return the found item.
variantDefault = (colorId, sizeId) => this.props.values.find(
({ id }) => id === [colorId, sizeId][this.props.index]
) || [];

The use of Array.prototype.filter seems more fitting.
variantDefault = (colorId, sizeId) => {
if (this.props.index.isBetween(0, arguments.length, 1)) return [];
var compareTo = arguments[this.props.index];
return this.props.values.filter(item => item.id === compareTo);
};
If you only want to return the last element found (which is what you are doing in your example) then add an Array.prototype.pop call to the filtered array.
You can add the isBetween function by doing:
if (typeof Number.prototype.isBetween !== "function") {
Number.prototype.isBetween = function(start, end, inclusive) {
if (typeof start !== "number" || isNaN(start)) throw Error("Start is not a number");
if (typeof end !== "number" || isNaN(end)) throw Error("End is not a number");
return inclusive ? start <= this && this <= end : start < this && this < end;
};
}

Related

find the overlap between two strings

I have a string and need to check with and get whether the following strings overlap with the start and end of my target string:
target string: "click on the Run"
search strings: "the Run button to", "code and click on"
Apparently:
"the Run button to" is overlapped at the end of target "click on the Run"
"code and click on" is overlapped at the start of target "click on the Run"
Both, "the Run" and "click on" will be the desired results.
I have come up with a function to check and get the overlapped results for the cases at the start and at the end separately.
Question:
But my code could not be able to get the expected results only if I know how the search string overlapped with the target string in the very first place. And how can I combine the searched results in one go as well?
function findOverlapAtEnd(a, b) {
if (b.length === 2) {
return "";
}
if (a.indexOf(b) >= 0) {
return b;
}
if (a.endsWith(b)) {
return b;
}
return findOverlapAtEnd(a, b.substring(0, b.length - 1));
}
function findOverlapAtStart(a, b) {
if (b.length === 2) {
return "";
}
if (a.indexOf(b) >= 0) {
return b;
}
if (a.startsWith(b)) {
return b;
}
return findOverlapAtStart(a, b.substring(1));
}
console.log(findOverlapAtEnd("click on the Run", "the Run button to"))
console.log(findOverlapAtStart("click on the Run", "code and click on"))
edited:
case in the middle is also considered, e.g.:
target string: "click on the Run"
search strings: "on the"
Return value: "on the"
You may try this
function findOverlapAtEnd(a, b, min) {
if (b.length <= min) {
return '';
}
if (a.indexOf(b) >= 0) {
return b;
}
if (a.endsWith(b)) {
return b;
}
return findOverlapAtEnd(a, b.substring(0, b.length - 1), min);
}
function findOverlapAtStart(a, b, min) {
if (b.length <= min) {
return '';
}
if (a.indexOf(b) >= 0) {
return b;
}
if (a.startsWith(b)) {
return b;
}
return findOverlapAtStart(a, b.substring(1), min);
}
const GetOverlappingSection = (target, search, min) => {
if (target.length < search.length) {
const tmp = target;
target = search;
search = tmp;
}
let overlap1 = findOverlapAtStart(target, search, min);
if (overlap1.length === 0) {
overlap1 = findOverlapAtEnd(target, search, min);
}
return overlap1;
};
const removeEmptyKeyword = overlap => {
let tmpFinaloverlap = [];
overlap.forEach((key, idx) => {
if (!(key.trim().length === 0)) {
tmpFinaloverlap = [...tmpFinaloverlap, key];
}
});
return tmpFinaloverlap;
};
// let overlap = ['click on','the Run']
const GetOverlappingOfKeyowrd1And2 = (keywordSet1, keywordSet2,min) => {
let resultSetoverlap = [];
let tmpresultSetoverlap = [];
keywordSet1.forEach(key =>
keywordSet2.forEach(k2 => {
tmpresultSetoverlap = [
...tmpresultSetoverlap,
GetOverlappingSection(key, k2, min),
];
})
);
// get the resultSetoverlap
tmpresultSetoverlap.forEach(element => {
if (element.length > 0) {
resultSetoverlap = [...resultSetoverlap, element];
}
});
return resultSetoverlap;
};
const min = 2;
//To handle overlapping issue in overlapping set, that casuing
overlap.forEach((key, idx) => {
if (idx < overlap.length - 1) {
for (let i = idx + 1; i < overlap.length; i++) {
console.log(`key: ${key}`);
console.log(`search: ${overlap[i]}`);
let overlapSection = GetOverlappingSection(key, overlap[i], min);
if (overlapSection.length > 0) {
console.log(`overlapSection: ${overlapSection}`);
overlap[idx] = overlap[idx].replace(overlapSection, '');
}
}
}
});
overlap = removeEmptyKeyword(overlap);
console.log(overlap);
overlap.forEach(key => {
keywordSet2 = keywordSet2.map((k1, idx) => {
console.log(`checking overlap keyword:'${key}' in '${k1}'`);
return k1.replace(key, '');
});
});
overlap.forEach(key => {
keywordSet1 = keywordSet1.map((k1, idx) => {
console.log(`checking overlap keyword:'${key}' in '${k1}'`);
return k1.replace(key, '');
});
});
keywordSet2 = removeEmptyKeyword(keywordSet2);
keywordSet1 = removeEmptyKeyword(keywordSet1);
overlap.forEach(key => {
text = text.replace(key, `$#k1k2$&$`);
});
keywordSet1.forEach(key => {
text = text.replace(key, `$#k1$&$`);
});
keywordSet2.forEach(key => {
text = text.replace(key, `$#k2$&$`);
});
console.log(`ResultSetoverlap after processing:${text}`);
Because I need to decompress and I find these logic puzzles fun, here's my solution to the problem...
https://highdex.net/begin_end_overlap.htm
You can view source of the page to see JavaScript code I used. But just in case I ever take that page down, here's the important function...
function GetOverlappingSection(str1, str2, minOverlapLen = 4) {
var work1 = str1;
var work2 = str2;
var w1Len = work1.length;
var w2Len = work2.length;
var resultStr = "";
var foundResult = false;
var workIndex;
if (minOverlapLen < 1) { minOverlapLen = 1; }
else if (minOverlapLen > (w1Len > w2Len ? w2Len : w1Len)) { minOverlapLen = (w1Len > w2Len ? w2Len : w1Len); }
//debugger;
//we have four loops to go through. We trim each string down from each end and see if it matches either end of the other string.
for (var i1f = 0; i1f < w1Len; i1f++) {
workIndex = work2.indexOf(work1);
if (workIndex == 0 || (workIndex != -1 && workIndex == w2Len - work1.length)) {
//we found a match!
foundResult = true;
resultStr = work1;
break;
}
work1 = work1.substr(1);
if (work1.length < minOverlapLen) { break; }
}
if (!foundResult) {
//debugger;
//reset the work vars...
work1 = str1;
for (var i1b = 0; i1b < w1Len; i1b++) {
workIndex = work2.indexOf(work1);
if (workIndex == 0 || (workIndex != -1 && workIndex == w2Len - work1.length)) {
//we found a match!
foundResult = true;
resultStr = work1;
break;
}
work1 = work1.substr(0, work1.length - 1);
if (work1.length < minOverlapLen) { break; }
}
}
if (!foundResult) {
//debugger;
//reset the work vars...
work1 = str1;
for (var i2f = 0; i2f < w2Len; i2f++) {
workIndex = work1.indexOf(work2);
if (workIndex == 0 || (workIndex != -1 && workIndex == w1Len - work2.length)) {
//we found a match!
foundResult = true;
resultStr = work2;
break;
}
work2 = work2.substr(1);
if (work2.length < minOverlapLen) { break; }
}
}
if (!foundResult) {
//debugger;
//reset the work vars...
work2 = str2;
for (var i2b = 0; i2b < w2Len; i2b++) {
workIndex = work1.indexOf(work2);
if (workIndex == 0 || (workIndex != -1 && workIndex == w1Len - work2.length)) {
//we found a match!
foundResult = true;
resultStr = work2;
break;
}
work2 = work2.substr(0, work2.length - 1);
if (work2.length < minOverlapLen) { break; }
}
}
return resultStr;
}
Hopefully that's helpful.

Render text depending on matching API Results - Axios/JS

I have this working, but it does consume quite a lot of space.
I'm wondering if there is way to refactor it more, matching API results with a smaller refactored condition, perhaps?
axios.js
import axios from 'axios';
export const Models = () => {
return axios.get('data/cars.json')
.then(response => {
return response.data
})
}
file.js
import { Models } from './axios';
let carModels = Models();
carModels.then((result) => {
var i, j, match;
match = false;
for (i = 0; i < result.length; i++) {
for (j = 0; j < result[i].countries.length; j++) {
if (result[i].countries[j].price == price &&
result[i].color == color &&
result[i].brand == brand &&
result[i].model == model &&
result[i].speed == speed)
{
match = true;
return document.querySelector('#brandTitle').textContent = result[i].brand;
}
}
}
if (match == false) {
console.log('No match found.');
}
})
you can use some() that will make sure to terminate the loop as conditions met
carModels.then(result => {
var i, j, match;
match = false;
for (i = 0; i < result.length; i++) {
match = result[i].countries.some(country => {
if (
country.price == price &&
result[i].color == color &&
result[i].brand == brand &&
result[i].model == model &&
result[i].speed == speed
) {
document.querySelector('#brandTitle').textContent = result[i].brand;
return;
}
});
}
if (match == false) {
console.log('No match found.');
}
});
to make more efficient you can use some on parent loop also
carModels.then(result => {
var match;
match = false;
result.some(res => {
match = result[i].countries.some(country => {
if (
country.price == price &&
res.color == color &&
res.brand == brand &&
res.model == model &&
res.speed == speed
) {
document.querySelector('#brandTitle').textContent = res.brand;
return;
}
});
if (match) {
return;
}
});
if (match == false) {
console.log('No match found.');
}
});

How to make multiple conditions inside single filter

I am trying to make a filter based on checkboxes.
The thing is js ignoring other conditions inside filter when one is active
filterData() {
return this.airlines.filter(x => {
if (this.filters.options.length != 0 || this.filters.airlines.length != 0) {
for (let i = 0; this.filters.options.length > i; i++) {
if (this.filters.options[i] == 0) {
return x.itineraries[0][0].stops == 0;
}
if (this.filters.options[i] == 1) {
return x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
}
}
} else {
return x;
}
})
}
I know that return will stop the current loop, but is there any way to do it correctly?
Update-1: (When to filter record for every case checked OR case)
Replace for loop and all conditions in a single return by && for if and || condition for data:
var chbox = this.filters.options;
return $.inArray(0, chbox) != -1 && x.itineraries[0][0].stops == 0
|| $.inArray(1, chbox) != -1 && x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
Hope this helps !!
$.inArray(value, arr) method will check for each checkboxes and will work for every checked ones .
Update-2 (When to filter record for every case checked AND case)
As per comment below, you are trying to use checkbox on demand so use below code:
var chbox = this.filters.options;
boolean condition = true;
if ($.inArray(0, chbox) != -1) {
conditon = conditon && x.itineraries[0][0].stops == 0;
}
if ($.inArray(1, chbox) != -1) {
conditon = conditon && x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
}
return condition;
Your filter function is returning an object, which ideally should be a boolean value. Please refactor the code as below.
filterData() {
return this.airlines.filter(x => {
let result = false;
if (this.filters.options.length != 0 || this.filters.airlines.length != 0) {
for (let i = 0; this.filters.options.length > i; i++) {
if (this.filters.options[i] == 0) {
result = x.itineraries[0][0].stops == 0;
break;
} else if (this.filters.options[i] == 1) {
result = x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
break;
}
}
}
return result;
})
}

VueJS for loop creating components, components seem to be linked

i'm doing a for loop on an array, for each value i'm creating a component. I was under the impression that I need to put a key on the for loop so that Vue knows it is unique?
<div v-for="hours in location.hours" class="businessHours" :key="hours.id">
<business-hours :response="hours" :unique-key="uniqueKey" :default-weekdays="response.weekdays">
<div slot-scope="{ hours, weekdays, title, uniqueKey, toggle, inArray, componentKey }">
<div class="panel-heading v-center">
<div class="field">
Within this component I have got some logic that just selects/deselected checkboxes, however these 2 components seem to be linked. When I click checkboxes on one of them, the other one changes too!
This is my component:
<template>
<div>
<slot :hours="response" :weekdays="weekdays" :title="title" :toggle="toggle" :inArray="inArray" :componentKey="componentKey"></slot>
</div>
</template>
<script>
export default {
props: [ 'response', 'uniqueKey', 'defaultWeekdays' ],
data: function() {
return {
weekdays: this.response.weekdays,
componentKey: this.key()
}
},
created() {
if (this.weekdays === undefined) {
this.weekdays = this.defaultWeekdays;
}
},
methods: {
title: function() {
if (this.weekdays === undefined) return;
let selected = Object.keys(this.weekdays).filter((e) => { if (this.weekdays[e].selected) return e });
if (selected.length === 0) return;
let start = this.weekdays[parseInt(selected[0])].value;
let end = this.weekdays[parseInt(selected[selected.length - 1])].value;
if (start === end) {
return start.charAt(0).toUpperCase() + start.substring(1);
}
return start.charAt(0).toUpperCase() + start.substring(1) + ' - ' + end.charAt(0).toUpperCase() + end.substring(1);
},
toggle: function(index) {
let clicked = this.weekdays[index];
let action = clicked.selected ? 'remove' : 'add';
let selected = Object.keys(this.weekdays).filter((i) => { if (this.weekdays[i].selected) return i });
let start = parseInt(selected[0]);
let middle = parseInt(selected[Math.floor(selected.length / 2)]);
let end = parseInt(selected[selected.length - 1]);
if (isNaN(start) && isNaN(middle) && isNaN(end)) {
start = middle = end = index;
}
// Add and remove multiple days
if (index < (start - 1) && action === 'add') {
for (let i = index; i <= (start - 1); i++) {
this.weekdays[i].selected = true;
}
}
if (index > start && index < middle && action === 'remove') {
for (let i = start; i <= index; i++) {
this.weekdays[i].selected = false;
}
}
if (index > (end + 1) && action === 'add') {
for (let i = end + 1; i <= index; i++) {
this.weekdays[i].selected = true;
}
}
if (index < end && index >= middle && action === 'remove') {
for (let i = index; i <= end; i++) {
this.weekdays[i].selected = false;
}
}
// Add and remove single days
if ((index === (end + 1) || index === (start - 1)) || (index === end || index === start) && action === 'add') {
this.weekdays[index].selected = true;
}
if ((index === end || index === start) && action === 'remove') {
this.weekdays[index].selected = false;
}
},
inArray: function(needle) {
let length = this.weekdays.length;
for(let i = 0; i < length; i++) {
if(this.weekdays[i] === needle) return true;
}
return false;
},
key: function() {
return Math.random().toString(36).replace(/[^a-z0-9]+/g, '').substr(0, 10);
}
}
}
</script>
Can someone lend me a hand here as to why this is happening?

Javascript If Condition not evaluating correctly

I have a section of code where a variable contains a particular string (here it's multiply), and when I check if the variable has that particular string, the condition always equates to false. I cannot find what I'm missing here.
// calculations
$scope.$watch('colInput.' + el.key, function () {
angular.forEach($scope.colInput[el.key], function (item, index) {
angular.forEach($scope.column[el.key], function (item_1, index_1) {
if (item.hasOwnProperty(item_1.key)) {
item[item_1.key].type = item_1.type;
item[item_1.key].id = item_1.id;
item[item_1.key].options = item_1.options;
}
else {
item[item_1.key] = {};
item[item_1.key].type = item_1.type;
item[item_1.key].id = item_1.id;
item[item_1.key].options = item_1.options;
}
})
angular.forEach(item, function (elem, key) { //each column of the row
var operand_1, operator, operand_2;
if (elem.type == 10) {
// analyzing the formula
elem.options.forEach(function (el, index) {
if (isNaN(el) && index == 1) {
operator = el;
} else if (isNaN(el) && index == 0) {
operand_1 = el;
} else if (isNaN(el) && index == 2) {
operand_2 = el;
} else if (!isNaN(el)) {
operand_2 = parseFloat(el);
}
})
console.log(operator, eval(operator === "multiply"), typeof operator);
if (operator == 'multiply') {
console.log("IF---")
elem.value = parseFloat(item[operand_1].value) * operand_2;
}
}
})
})
}, true)
It looks like your operator is an HTML element not a String.
The comparison with multiply will always be false.

Categories

Resources