Combine Array Of Strings With String - javascript

I need to combine the LAST fromAddress and toAddresses values into just one set of array without duplication and without the loginUser.
Expected Output
{ "newResponse": ["james#gmail.com", "ken#yahoo.com"] }
const loginUser = "jane#gmail.com"
const old = [
{
"toAddresses": ["joker#gmail.com", "jake#gmail.com"],
},
{
"fromAddress": "ken#yahoo.com",
"toAddresses": ["jane#gmail.com", "james#gmail.com"],
}
];
let emailLength = old?.length - 1
let email = old[emailLength]
const newResponse = Array.from(new Set([...email.map(x => [...x.toAddresses].concat([...x.fromAddress || []]))]))
console.log(newResponse)

const loginUser = "jane#gmail.com"
const old = [
{
"toAddresses": ["joker#gmail.com", "jake#gmail.com"],
},
{
"fromAddress": "ken#yahoo.com",
"toAddresses": ["jane#gmail.com", "james#gmail.com"],
}
];
let last = old[old.length - 1];
let combined = new Set([last.fromAddress, ...last.toAddresses]);
combined.delete(loginUser);
let newResponse = Array.from(combined);
console.log({newResponse});

You're trying to call map on an object, but is only an array method.
You can just access the properties directly on the email object, since you know what you're looking for you don't need to iterate on it.
Then filter the array for the logged in user and construct a new object for the response.
const loginUser = "jane#gmail.com"
const old = [
{
"toAddresses": ["joker#gmail.com", "jake#gmail.com"],
},
{
"fromAddress": "ken#yahoo.com",
"toAddresses": ["jane#gmail.com", "james#gmail.com"],
}
];
let emailLength = old?.length - 1
let email = old[emailLength]
let addresses = Array.from(new Set([...email.toAddresses, email.fromAddress]))
addresses = addresses.filter(addy => addy !== loginUser)
const newResponse = { "newResponse": addresses }
console.log(newResponse)

Related

Enabling multiple filters for a single array

in my application, there are two types of filters, category and country. However, I am not able to get them to be applied at the same time. For example, I only want the intersection of Category: SaaS + Country: Singapore.
Any advice?
const loadData = props.load
const [card, setCard] = useState(loadData)
const [searchPhrase, setSearchPhrase] = useState("")
const search = (event)=>{
const matchedUsers = loadData.filter((card)=>{
return card.title.toLowerCase().includes(event.target.value.toLowerCase())
})
setCard(matchedUsers)
setSearchPhrase(event.target.value)
}
const filterCountry = (event)=>{
const filteredCards = loadData.filter((card)=>{
return card.country.includes(event.target.value)
})
setCard(filteredCards)
}
const filterCat = (event)=>{
const filteredCards = loadData.filter((card)=>{
return card.cat.includes(event.target.value)
})
setCard(filteredCards)
}
You can change your filter condition to check if the value is in all your considered types
const result = yourData.filter(item => item.country.includes(YOURPHRASE) || item.cat.includes(YOURPHRASE))
you can pass the filtered array as a parameter to the filtering functions :
const search = (event)=>{
const matchedUsers = loadData.filter((card)=>{
return card.title.toLowerCase().includes(event.target.value.toLowerCase())
})
setSearchPhrase(event.target.value);
return matchedUsers
}
const filterCountry = (event,array)=>{
return array.filter((card) => card.country.includes(event.target.value);
}
const filterCat = (event,array)=>{
return array.filter((card) => card.cat.includes(event.target.value);
}
useEffect(() => {
let result = matchedUsers();
result = filterCountry(result);
result = filterCat(result);
setArrayToFilter(result);
}, [searchPhrase]);

Creating an Array of Likes from Javascript Functions

These are parts of my entire code. So what I am trying to do is create separate arrays of the values I like or dislike and output them in my html File onclick. I tried to create an empty array and push value but my final array ends up empty.
Script.js
const showRandomMovie = async() => {
const movieInfo = document.getElementById('movieInfo');
if (movieInfo.childNodes.length > 0) {
clearCurrentMovie();
};
const movies = await getMovies();
const randomMovie = getRandomMovie(movies);
const info = await getMovieInfo(randomMovie);
displayMovie(info);
};
playBtn.onclick = showRandomMovie;
helper.js
const displayMovie = (movieInfo) => {
const moviePosterDiv = document.getElementById('moviePoster');
const movieTextDiv = document.getElementById('movieText');
const likeBtn = document.getElementById('likeBtn');
const dislikeBtn = document.getElementById('dislikeBtn');
// Create HTML content containing movie info
const moviePoster = createMoviePoster(movieInfo.poster_path);
const titleHeader = createMovieTitle(movieInfo.title);
const overviewText = createMovieOverview(movieInfo.overview);
const releaseHeader = createReleaseDate(movieInfo.release_date)
// Append title, poster, and overview to page
moviePosterDiv.appendChild(moviePoster);
movieTextDiv.appendChild(titleHeader);
movieTextDiv.appendChild(overviewText);
movieTextDiv.appendChild(releaseHeader)
showBtns();
likeBtn.onclick = likeMovie;
dislikeBtn.onclick = dislikeMovie;
};
const likeMovie = () => {
clearCurrentMovie();
showRandomMovie();
};
// After disliking a movie, clears the current movie from the screen and gets another random movie
const dislikeMovie = () => {
clearCurrentMovie();
showRandomMovie();
};
Create arrays for the likes and dislikes and push it to an array. Pass it along to your methods.
likeBtn.onclick = () => rateMovie('likes', movieInfo);
dislikeBtn.onclick = () => rateMovie('dislikes', movieInfo);
have the method add it to the array
const ratings = {
likes: [],
dislikes: [],
};
const rateMovie = (type, data) => {
ratings[type].push(data);
clearCurrentMovie();
showRandomMovie();
};

Add documentID of fetched document to array in firebase cloud function

I have a cloud function that "Joins" data from a list of documents in a collection.
I then return the result as an array, but I want to return the documentId as well (doc.id) in the list that i return.
How can i do that?
const restData = [];
//const userId = ctx.auth.uid;
const userId = 'dHAP1CNN6LhJWddQoTqyIkqIjhB2'; // !!! TEST ONLY
const all = await db.collection(`/customers/${userId}/lunch_cards`).listDocuments().then((snapshot) => {
snapshot.forEach(doc => {
const nextData = db.collection(`/restaurants`).doc(doc.id).get();
const newData = {...nextData, documentId: doc.id}; <-- This does not work only documentId isout in newData
console.log(util.inspect(newData));
restData.push(nextData);
console.log(doc.id);
});
});
const snaps = await Promise.all(restData);
const responseArray = snaps.map((s) => {return s.data()});
return responseArray;
I solved it!
Solution:
Just adding a new string to the array :)
const responseArray = snaps.map((s) => {
const snapData = s.data();
if (snapData) {
snapData['id'] = s.id;
}
return snapData;
});

How to filter array item based on string with regex?

The purpose of filter() is to remove currentGroup matching with URLs from the array. It doesn't matter there is numbers after Malappuram/123456/12 or not. Is there any best way to do it in ES6 ?
DEMO: https://jsbin.com/jozuqameto/edit?js,console
const initialLinks = [
"http://www.lchfmalayalam.com",
"https://t.me/Malappuram",
"https://t.me/keraladevelopers/42716",
"http://www.whatsapp.com",
"https://www.youtube.com/watch?v=BnbFRSyHIl4",
"http://google.com",
"https://t.me/joinchat/NHNd1hcSMCoYlnZGSC_H7g",
"https://t.me/keraladevelopers/",
"http://t.me/keraladevelopers",
"http://athimannil.com/react/",
"http://athimannil.info/",
"https://t.me/hellomates/5",
"http://t.me/Malappuram/32156",
"http://t.me/keraladevelopers/42716",
"http://t.me/joinchat/NHNd1hcSMCoYlnZGSC_H7g",
"http://t.me/keraladevelopers/",
"http://t.me/hellomates/5"
];
const normalizeTme = R.replace(
/^(?:#|(?:https?:\/\/)?(?:t\.me|telegram\.(?:me|dog))\/)(\w+)(\/.+)?/i,
(_match, username, rest) => {
return /^\/\d+$/.test(rest) ?
`https://t.me/${username.toLowerCase()}` :
`https://t.me/${username.toLowerCase()}${rest || ""}`;
}
);
const filterOwnLinks = groupUsername => {
return R.match(
/^(?:#|(?:https?:\/\/)?(?:t\.me|telegram\.(?:me|dog))\/)(\w+)(\/.+)?/i,
(_match, username, rest) => {
if (username) {
return currentGroup.toLowerCase() !== username.toLowerCase();
}
return true;
}
);
};
const currentGroup = "Malappuram";
const urls = R.uniq(initialLinks)
.filter(filterOwnLinks)
.map(normalizeTme);
console.log(initialLinks);
console.log(urls);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
You can use URL api to parse url, and take the pathname from parse url object, and check if starts with currentGroup
const initialLinks = ["http://www.lchfmalayalam.com","https://t.me/Malappuram","https://t.me/keraladevelopers/42716","http://www.whatsapp.com","https://www.youtube.com/watch?v=BnbFRSyHIl4","http://google.com","https://t.me/joinchat/NHNd1hcSMCoYlnZGSC_H7g","https://t.me/keraladevelopers/","http://t.me/keraladevelopers","http://athimannil.com/react/","http://athimannil.info/","https://t.me/hellomates/5","http://t.me/Malappuram/32156","http://t.me/keraladevelopers/42716","http://t.me/joinchat/NHNd1hcSMCoYlnZGSC_H7g","http://t.me/keraladevelopers/","http://t.me/hellomates/5"];
const currentGroup = "Malappuram";
const urls = [...new Set(initialLinks)]
let final = urls.filter(url => {
let parsed = new URL(url)
let pattern = new RegExp(`^\/${currentGroup}`,'i')
return !pattern.test(parsed.pathname)
})
console.log(final)
You could test with a simple regular expression within the Array.prototype.filter callback:
const initialLinks = [
"http://www.lchfmalayalam.com",
"https://t.me/Malappuram",
"https://t.me/keraladevelopers/42716",
"http://www.whatsapp.com",
"https://www.youtube.com/watch?v=BnbFRSyHIl4",
"http://google.com",
"https://t.me/joinchat/NHNd1hcSMCoYlnZGSC_H7g",
"https://t.me/keraladevelopers/",
"http://t.me/keraladevelopers",
"http://athimannil.com/react/",
"http://athimannil.info/",
"https://t.me/hellomates/5",
"http://t.me/Malappuram/32156",
"http://t.me/keraladevelopers/42716",
"http://t.me/joinchat/NHNd1hcSMCoYlnZGSC_H7g",
"http://t.me/keraladevelopers/",
"http://t.me/hellomates/5"
];
const getCurrentGroupLinks = (links, regex) => {
return links.filter(link => !regex.test(link));
};
console.log(getCurrentGroupLinks(initialLinks, /Malappuram/));

Get object in array that contains closest matching id property in a string?

I am wondering if there is a better way to do get the result.
I have an array of objects, each object contains an id as a string path pattern. I want to return the object that has the best match to a url path. ATM I am using lodash
All id's are unique.
const url = '/economia/finanzas/moodys-coloca-calificaciones-de-riesgo-de-costa/JZF24QAQHBBFPLJQL5VZJPKCZA/story/'
const sites = [{
'_id': '/la-nacion/economia'
}, {
'_id': '/la-nacion'
}, {
'_id': '/la-nacion/economia/finanzas'
}, {
'_id': '/la-nacion/economia/moodys'
}]
const urlArr = url.split('/')
const compare = sites.map(site => {
// get all matches
const siteArr = site._id.split('/')
// get lengths of matches
return _.intersection(siteArr, urlArr).length
})
// get index of obj with best match
const indexOfBestMatch = _.indexOf(compare, _.max(compare))
// new primary section
const newPrimarySection = sites.filter((e, i) => {
return i === indexOfBestMatch
})
console.log(newPrimarySection)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
https://jsbin.com/lumepereyi/1/edit?js,console
No need for a library, you can use reduce to iterate over the array of _ids, keeping a count of the number of substring matches, so that it resolves to the one with the most matches:
const url = '/economia/finanzas/moodys-coloca-calificaciones-de-riesgo-de-costa/JZF24QAQHBBFPLJQL5VZJPKCZA/story/';
const sites = [{
'_id': '/la-nacion/economia'
}, {
'_id': '/la-nacion'
}, {
'_id': '/la-nacion/economia/finanzas'
}, {
'_id': '/la-nacion/economia/moodys'
}];
const substrings = new Set(url.split('/'));
const countMatches = str => str.split('/').reduce((a, substr) => a + (substrings.has(substr)), 0);
const { bestMatch } = sites.reduce(({ bestMatch, count=0 }, { _id }) => {
const thisCount = countMatches(_id);
return thisCount > count
? { count: thisCount, bestMatch: _id }
: { count, bestMatch };
}, {});
console.log(bestMatch);
Since you only need the item with the max matches, you can use _.maxBy() to iterate the array of sites, and extract the item. Use _.get() to extract the value of _id, because _.get() won't throw an error if sites is empty:
const url = '/economia/finanzas/moodys-coloca-calificaciones-de-riesgo-de-costa/JZF24QAQHBBFPLJQL5VZJPKCZA/story/'
const sites = [{"_id":"/la-nacion/economia"},{"_id":"/la-nacion"},{"_id":"/la-nacion/economia/finanzas"},{"_id":"/la-nacion/economia/moodys"}]
const getPrimarySection = (url, sites) => {
const urlArr = url.split('/')
return _.get(_.maxBy(sites, site => {
const siteArr = site._id.split('/')
return _.intersection(siteArr, urlArr).length
}), '_id')
}
const newPrimarySection = getPrimarySection(url, sites)
console.log(newPrimarySection)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
If your path prefix is always the same (like it seems it is with /la-naction then you could do your own scoring (via startsWith) based on the length of the matched string and then sort-by desc (biggest score) ... and take the top score:
const url = '/economia/finanzas/moodys-coloca-calificaciones-de-riesgo-de-costa/JZF24QAQHBBFPLJQL5VZJPKCZA/story/'
const sites = [{"_id":"/la-nacion/economia"},{"_id":"/la-nacion"},{"_id":"/la-nacion/economia/finanzas"},{"_id":"/la-nacion/economia/moodys"}]
const getBestMatch = (s, u, p = '/la-nacion') => { // <-- default prefix
const topScored = s.map(x =>
(Object.assign(x, {
score: ((`${p}${u}`).startsWith(x._id) ? x._id.length : 0)}), x)
).sort((a, b) => b.score - a.score)[0] // <-- sort, get the highest score
return topScored.score > 0 ? topScored._id : undefined
}
console.log(getBestMatch(sites, url))
No lodash neeed etc it is just map to add the score and then sort really.

Categories

Resources