Reputation: 3543
I have a given checkIDs
array referring ids of phrases
object.
I want to modify the checkIDs
and return a new array using removeSameTranslates
function so that there are only ids inside checkIDs
with unique translates.
Lets say in phrases object we have 1 and 5 with exact same translate. if we have const checkIDs = [1,5];
then we should only keep the first one and return [1]
as the final result. because translate of 1 and 5 are equel.
const phrases = {
1: {ref: 'some English text', translate: 'some translation1'},
2: {ref: 'some English text2', translate: 'some translation2'},
3: {ref: 'some English text3', translate: 'some translation8'},
4: {ref: 'some English text4', translate: 'some translation3'},
5: {ref: 'some English text4', translate: 'some translation1'},
}
// 1 and 5 both point to a phrase with same translate so we should only keep one
const checkIDs = [1,2,3,5];
const newIDs = removeSameTranslates(checkIDs);
console.log(newIDs);
// remove one of the ids with equel translations and return new array of ids
function removeSameTranslates(checkIDs) {
// should return [1,2,3]
}
Upvotes: 1
Views: 98
Reputation: 22
This should work for your scenario:
const phrases = {
1: {ref: 'some English text', translate: 'some translation1'},
2: {ref: 'some English text2', translate: 'some translation2'},
3: {ref: 'some English text3', translate: 'some translation8'},
4: {ref: 'some English text4', translate: 'some translation3'},
5: {ref: 'some English text4', translate: 'some translation1'},
}
// 1 and 5 both point to a phrase with same translate so we should only keep one
const checkIDs = [1, 2, 3, 5];
const newIDs = removeSameTranslates(checkIDs);
console.log(newIDs);
// remove one of the ids with equel translations and return new array of ids
function removeSameTranslates(checkIDs) {
newIDs_ = checkIDs;
for (let i = 0; i < newIDs_.length; i++) {
for (let j = i + 1; j < checkIDs.length; j++) {
if (phrases[newIDs_[j]].translate == phrases[newIDs_[i]].translate) {
newIDs_.splice(j, 1);
}
}
}
return (newIDs_);
}
A quick explanation of what we did in the removeSameTranslates function: First of we create a new array variable called newIDs_ that is equal to checkers. We create a new variable so that when we delete the same id from the newIDs_ it doesn't effect the checkIDs array. We added the _ next to the newIDs variable name so the name is newIDs variable name, if it was then deleting the same id from in this function would immediately change the value of the newIDs array. That would also work but then we wouldn't need to return the new array in the function, and you said you want the function to do that. then we have a for loop which goes through all of the elements in the checkIDs array. Then we have another for loop that goes again through all the elements in the chekIds array but it starts from the next one after the current element we are checking in the first for loop. for example when we go through the first for loop and we start at the first element the next for loop will go through all the elements after that one so the second, third,. fourth and so on. ion the second for loop we basically check if the any of the elements that come after the element that we are checking in the first array come up again and if the do we remove them with the function .splice(j,1); (j in splice means we are going to remove some elements at the j index and 1 mean that we want to remove 1 element ) at the end we return the newly created array. IF YOU DON'T UNDERSTAND THIS I HIGHLY RECOMMEND YOU READ THROUGH THESE WEBSITES: arrays array_methods cuz you need to understand how for loops, and arrays work in javascript. I hope you understand the solution and not just copy it have fun :).
Upvotes: 1
Reputation: 16908
We can do it using Array#reduce
.
The Array#reduce
is used iterate over and check if the translate
occurred before or not in the set seen
, if not add it in the output else discard that id :
const phrases = {
1: {ref: 'some English text', translate: 'some translation1'},
2: {ref: 'some English text2', translate: 'some translation2'},
3: {ref: 'some English text3', translate: 'some translation8'},
4: {ref: 'some English text4', translate: 'some translation3'},
5: {ref: 'some English text4', translate: 'some translation1'},
};
const checkIDs = [1, 2, 3, 5];
const newIDs = removeSameTranslates(checkIDs, phrases);
console.log(newIDs);
function removeSameTranslates(checkIDs, phrases) {
const seen = new Set();
return checkIDs.reduce((r, o) => {
if (!seen.has(phrases[o].translate)) {
seen.add(phrases[o].translate);
r.push(o)
}
return r;
}, []);
}
Upvotes: 1
Reputation: 9364
Another approach using reduce
and Object.values
:
const phrases = {
1: {ref: 'some English text', translate: 'some translation1'},
2: {ref: 'some English text2', translate: 'some translation2'},
3: {ref: 'some English text3', translate: 'some translation8'},
4: {ref: 'some English text4', translate: 'some translation3'},
5: {ref: 'some English text4', translate: 'some translation1'},
}
const checkIDs = [1,2,3,5];
const newIDs = removeSameTranslates(checkIDs, phrases);
console.log(newIDs);
function removeSameTranslates(checkIDs, phrases) {
const result = checkIDs.reduce((obj, id) => {
obj[phrases[id].translate] = obj[phrases[id].translate] || id;
return obj;
}, {});
return Object.values(result);
};
This works by inverting the phrases
object so that the key is the value of the translate
property. You can then reference this key to determine whether it has already been assigned an id.
Upvotes: 1
Reputation: 25648
You could use a combination of map
, reduce
and every
:
const phrases = {
1: {ref: 'some English text', translate: 'some translation1'},
2: {ref: 'some English text2', translate: 'some translation2'},
3: {ref: 'some English text3', translate: 'some translation8'},
4: {ref: 'some English text4', translate: 'some translation3'},
5: {ref: 'some English text4', translate: 'some translation1'},
};
const checkIDs = [1,2,3,5];
const newIDs = removeSameTranslates(checkIDs);
console.log(newIDs);
function removeSameTranslates(checkIDs) {
return checkIDs
.map(id => ({id, ...phrases[id]})) // Convert the IDs to Objects
.reduce(
(res, phrase) => {
if (res.every(p => p.translate !== phrase.translate)) { // Check translation
res.push(phrase);
}
return res;
},
[]
)
.map(({id}) => id); // Convert the Objects back to IDs
}
Upvotes: 4