How to compare array of objects to array? - javascript

I have an array of objects and array of strings
cities = [ { id: '1', name: 'Paris'}, { id: '2', name: 'Rome'}, { id: '3', name: 'London'}, { id: '4', name: 'Barcelona'}]
userChoice = ['2','4']
I need to iterate over cities with userChoice and find name of cities by id.
I guess it's going to be a nested loop, but I am strugling with it.
cities.filter(city=> userChoice.forEach(choice => choice == city.id))

You can use filter() and includes() to filter cities array by checking if a city's id is present in userChoice array.
To get just the names, you can use map() to transform the result.
let cities = [ { id: '1', name: 'Paris'}, { id: '2', name: 'Rome'}, { id: '3', name: 'London'}, { id: '4', name: 'Barcelona'}];
let userChoice = ['2','4'];
let filteredCities = cities.filter(city => userChoice.includes(city.id));
let names = filteredCities.map(city => city.name);
console.log(names);

You could use a Map object to look up ID based on city.
let cityMap = new Map(cities.map(c => [c.name, c.id]));
console.log(cityMap.get("Rome")); // --> "2"

Just use a simple map, you map the array element to the city from the other array. You might want to put a null check in if you can have values that might not be in the array but for simplicity I left it out.
const cities = [ { id: '1', name: 'Paris'}, { id: '2', name: 'Rome'}, { id: '3', name: 'London'}, { id: '4', name: 'Barcelona'}];
const userChoice = ['2','4'];
const userCities = userChoice.map(val => cities.find(c => c.id === val).name);
console.log(userCities)

Related

Looping through inner array in a filter function in JS

I'm trying to filter the array here but the result seem to be empty. How do I loop through inner array in a filter function?
Below is the snippet
const carIds = ['100', '101'];
const carsList = [{
name: 'BMW',
id: '100'
}, {
name: 'Jeep',
id: '101'
}, {
name: 'Audi',
id: '103'
}];
const result = carsList.filter((val) => val.id === carIds.map((val) => val))
console.log('result', result)
Expected output should be
[{
name: 'BMW',
id: '100'
}, {
name: 'Jeep',
id: '101'
}]
Could anyone please advise?
I'm not completely sure what you're trying to do with the .map() method, but you're not using it right. .map() applies a transformation function to each element of the array, then returns a new array of the result. See the MDN article for help with the correct usage.
In your case, you can just use the .includes() method to check if the array includes the value. Like this:
const carIds = ['100', '101'];
const carsList = [{
name: 'BMW',
id: '100'
}, {
name: 'Jeep',
id: '101'
}, {
name: 'Audi',
id: '103'
}];
const result = carsList.filter(val => carIds.includes(val.id))
console.log('result', result)
Note that in this case, it is faster to use a Set, as it can check for membership in O(1) time rather than the O(n) that an array offers. Expand the snippet below for an example:
const carIds = new Set(['100', '101']);
const carsList = [{
name: 'BMW',
id: '100'
}, {
name: 'Jeep',
id: '101'
}, {
name: 'Audi',
id: '103'
}];
const result = carsList.filter(val => carIds.has(val.id))
console.log('result', result)
I'm guessing you want to return the cars who's ID's are included in the carIds array?
If so you want to use the .includes() method instead of .map().
const result = carsList.filter((val) => carIds.includes(val.id))

Filter object by property that starts with any of array elements

I have an object of contacts where I need to filter by the country code, for which I need to check if the ID of the contact (phone number) starts with any of the selected country codes array.
var countries = ['1', '91', '55', '972'];
var allContacts = [
{
id: '9123242135321',
name: 'Harun'
},
{
id: '905366365289',
name: 'Koray'
},
{
id: '135366365277',
name: 'Hayo'
},
{
id: '963923824212',
name: 'Bahaa'
},
{
id: '513324515689',
name: 'Hassan'
}];
I am looking for an efficient one-line solution without looping, so what I have tried before is:
allContacts.filter(c => c.id.some(l => countries.includes(l)));
But that worked if the id parameter is an array, and it searches the whole number instead of the beginning, what is the efficient way to filter the contacts which their id key startsWith any of the countries array values?
You need to iterate the countries and check with startsWith.
const
countries = ['1', '91', '55', '972'],
allContacts = [{ id: '9123242135321', name: 'Harun' }, { id: '905366365289', name: 'Koray' }, { id: '135366365277', name: 'Hayo' }, { id: '963923824212', name: 'Bahaa' }, { id: '513324515689', name: 'Hassan' }];
console.log(allContacts.filter(({ id }) => countries.some(c => id.startsWith(c))));

Remove equal objects from array

I have the following problem in JavaScript: I want to check an array for duplicates. My example array only has 6 objects here.
var list = [
{id: "1", label: "Nils"},
{id: "2", label: "Max"},
{id: "3", label: "Thomas"},
{id: "4", label: "Tom"},
{id: "5", label: "Joschua"},
{id: "5", label: "Joschua"}];
In the later project it can also be more than 500, which I import via a CSV file.
And now I want to remove duplicates. At first I tried the set method:
var newList = [... new Set(list)];
console.log(newList);
The result is false. The array has the same objects.
Then I tried a simple if query:
if(list[4]==list[5]){
console.log("equal") }else{
console.log("unequal")}
The result is unequal. I don't understand why.
The array should look like this:
[{ id: '1', label: 'Nils' },
{ id: '2', label: 'Max' },
{ id: '3', label: 'Thomas' },
{ id: '4', label: 'Tom' },
{ id: '5', label: 'Joschua' }]
If the ids are meant to be unique, you can use Array#filter with a Set based on the id.
var list = [
{id: "1", label: "Nils"},
{id: "2", label: "Max"},
{id: "3", label: "Thomas"},
{id: "4", label: "Tom"},
{id: "5", label: "Joschua"},
{id: "5", label: "Joschua"}];
const set = new Set,
res = list.filter(x => !set.has(x.id) && set.add(x.id));
console.log(res);
Set cannot compare object altogether, it only works with primitives types like number or string.
You can use a Map that is based on a key/value paradigm though, like :
const list = [
{id: '1',label: 'Nils'},
{id: '2', label: 'Max'},
{id: '3', label: 'Thomas'},
{id: '4', label: 'Tom'},
{id: '5', label: 'Joschua'},
{id: '5', label: 'Joschua'},
];
const map = new Map();
// Push the values into the map
list.forEach(({
id,
label,
}) => map.set(id, label));
// Transform the map into an array of object
const uniqueList = Array.from(map, ([id, label]) => ({
id,
label,
}));
console.log(uniqueList);
Or using an Array.reduce combined with an Array.map
const list = [
{id: '1', label: 'Nils'},
{id: '2', label: 'Max'},
{id: '3', label: 'Thomas'},
{id: '4', label: 'Tom'},
{id: '5', label: 'Joschua'},
{id: '5', label: 'Joschua'},
];
const uniqueList = Object.entries(list.reduce((tmp, {
id,
label,
}) => {
tmp[id] = label;
return tmp;
}, {})).map(([
id,
label,
]) => ({
id,
label,
}));
console.log(uniqueList);
Then I tried a simple if query:
if(list[4]==list[5]){ console.log("equal") }else{
console.log("unequal")} The result is unequal. I don't understand why.
== uses Abstract Equality Comparison Algorithm.
At first this algorithm checks if the types are the same
-> which they are.
Then the algorithm proceeds with the first step, and goes down to check if they both referencing the same object
-> they don't referencing the same object
That is the reason why it prints out false
Each usage of {} creates a new object, so this check fails and the result is false.
let a = {}
let b = {}
console.log(a==b);
Or like in your example
let a = {id: "5", label: "Joschua"};
let b = {id: "5", label: "Joschua"};
console.log(a==b);
Solution
To check if two objects are equal you can do the following
let a = {
id: 5,
name: "Max"
}
let b = {
id: 5,
name: "Max"
}
function areTheObjectsEqual(obj1, obj2) {
let keysObj1 = Object.keys(obj1);
let keysObj2 = Object.keys(obj2);
// first check if they have the same amount of keys, if not return false
if (keysObj1.length !== keysObj2.length) {
return false;
}
let valuesObj1 = Object.values(obj1);
let valuesObj2 = Object.values(obj2);
// then compare if they have the same values
for(let i = 0; i < valuesObj1.length; i++){
if(valuesObj1[i] !== valuesObj2[i]){
return false;
}
}
return true;
}
console.log(areTheObjectsEqual(a,b));

Filtering array of objects if specific key contains search term

I am trying to filter through an object with multiple key/value pairs by a specific key. It appears that the code I've written is searching the entire object regardless of the key...
If key name contains the search term, return the search term.
Array of Objects:
export const someArrayOfObjects = [
{ id: '1', name: 'Something' },
{ id: '2', name: 'Another' },
{ id: '3', name: 'Lets do one more' },
]
Search:
const searchResults = someArrayOfObjects.filter((o) =>
Object.keys(o).some((k) => o[k].toString().toLowerCase().includes(searchTerm.toLowerCase()))
);
So if I search "Something", I only want it to loop through name to search for that term...
You don't need the Object.keys loop.
const someArrayOfObjects = [
{ id: '1', name: 'Something' },
{ id: '2', name: 'Another' },
{ id: '3', name: 'Lets do one more' },
];
let key = 'name';
let searchTerm = 'th';
const res = someArrayOfObjects.filter(o =>
o[key].toLowerCase().includes(searchTerm.toLowerCase()));
console.log(res);
similar to iota's, you don't need to create the extra array with Object.keys.
just loop/check every item inside the original array with the 'name' key.
you can also try to make it more reusable like below.
const someArrayOfObjects = [
{ id: '1', name: 'Something' },
{ id: '2', name: 'Another' },
{ id: '3', name: 'Lets do one more' },
];
const search = function (anyArray, searchTerm) {
return anyArray.filter((obj) => {
if (obj.name === searchTerm) {
return obj.name;
}
return false;
});
};
const case1 = search(someArrayOfObjects, 'Something');
console.log(case1);

Find object in array ids

I've list of id's in array and list of article in other array.
I would like filter my article array by ids find in id's array.
Exemple :
const ids = [ '1', '2', '3' ];
const articles = [
{ id: '1', title: 'blua' },
{ id: '10', title: 'blua' }
...
];
I've try this :
ids.map((id) => {
return audits.find((audit) => {
return id === audit.id;
});
});
But return underfined :/
I think it's not a good methode ^^
Anyone can help me ?
Thank you !
Use array.prototype.filter and array.prototype.includes:
const ids = [ '1', '2', '3' ];
const articles = [ { id: '1', title: 'blua' },{ id: '10', title: 'blua' } ];
const filtered = articles.filter(a => ids.includes(a.id));
console.log(filtered);
const ids = [ '1', '2', '3' ];
const articles = [
{ id: '1', title: 'blua' },
{ id: '10', title: 'blua' }
...
];
let results = articles.filter( (a) => ids.indexOf(a.id) !== -1);

Categories

Resources