Search for all values in array of objects - javascript

I have three arrays.
One of them contains values I will be testing. The two others are arrays of object which might include the values of my first array under the name key.
const myArray = ["foo", "bar"];
const testArray1 = [
{name: "foo"},
{name: "bar"},
{name: "something else"}
]
const testArray2 = [
{name: "foo"},
{name: "rab"},
{name: "something else"}
]
I am trying to write a condition which would return true only if the tested array contains all of the values of my first array.
With the same example it would give me something like this :
if (testArray1.containsAll(myArray)) // true
if (testArray2.containsAll(myArray)) // false
What is the best way to resolve this ?
Thanks, any help much appreciated

With array.prototype.every and array.prototype.find, it should be:
const myArray = ["foo", "bar"];
const testArray1 = [
{name: "foo"},
{name: "bar"},
{name: "something else"}
];
const testArray2 = [
{name: "foo"},
{name: "rab"},
{name: "something"}
];
console.log(myArray.every(s => testArray1.find(o => o.name === s)));
console.log(myArray.every(s => testArray2.find(o => o.name === s)));

can be use, every and some. these are return only true/false
const myArray = ["foo", "bar"];
const testArray1 = [
{name: "foo"},
{name: "bar"},
{name: "something else"}
]
const testArray2 = [
{name: "foo"},
{name: "rab"},
{name: "something else"}
]
let result1 = testArray1.every(item => myArray.some(array => item.name == array))
let result2 = testArray2.every(item => myArray.some(array => item.name == array))
console.log('result1', result1)
console.log('result2', result2)

Check this out. May not be the best way but works perfectly fine.
const myArray = ["foo", "bar"];
const testArray1 = [
{name: "foo"},
{name: "bar"},
{name: "something else"}
]
const testArray2 = [
{name: "foo"},
{name: "rab"},
{name: "something else"}
]
let aFlag = testArray1.filter( a => myArray.includes(a.name)).length === myArray.length;
let bFlag = testArray2.filter( a => myArray.includes(a.name)).length === myArray.length;
console.log(aFlag, bFlag)

Related

Filtering two arrays with .filter [duplicate]

This question already has answers here:
Simplest code for array intersection in javascript
(40 answers)
Closed 2 years ago.
I'm trying to get information, a have all the data that i get from Database and now I need to do something that should be simple (but not for a novice like me xd), I'm trying to do the next filter in JS
const array1 = [{id: 'a'}, {id: '8'}, {id: 'c'}, {id: 'a'}];
const array2 = [{id: 'a'}, {id: 'c'}];
console.log(array1.filter(id => id.id == array2.id))
It doesn't returns me nothing, and I don't understand why, also I try to use:
console.log(array1.filter(id => id.id == array2.id))
My result is all the values from array1, I mean I only want the elements that have the same Id that array2 from array1, in other words, I want that its returns me 2 objects with Id = a and one with id = c
Use Array.some() inside Array.filter() callback method.
const array1 = [{id: 'a'}, {id: '8'}, {id: 'c'}, {id: 'a'}];
const array2 = [{id: 'a'}, {id: 'c'}];
const output = array1.filter(item1 => array2.some(item2 => item2.id === item1.id))
console.log(output);
This will return three objects, because in array1 there are two objects with id: a and one with id: c.
const array1 = [{id: 'a'}, {id: '8'}, {id: 'c'}, {id: 'a'}];
const array2 = [{id: 'a'}, {id: 'c'}];
let res = array1.filter(obj1 => array2.find(obj2 => obj1.id === obj2.id))
console.log(res)
You can filter out duplicate objects with Array.reduce():
const array1 = [{id: 'a'}, {id: '8'}, {id: 'c'}, {id: 'a'}];
const array2 = [{id: 'a'}, {id: 'c'}];
let res = array1.filter(obj1 => {
return array2.find(obj2 => obj1.id === obj2.id)
})
.reduce((acc,cur) => {
if(!acc.find(obj => obj.id === cur.id)){
acc.push(cur)
}
return acc
},[])
console.log(res)
You could take a Set and filter the array.
This approach takes a single loop for building the set and another for filtering.
const
array1 = [{ id: 'a' }, { id: '8' }, { id: 'c' }, { id: 'a' }],
array2 = [{ id: 'a' }, { id: 'c' }],
set2 = new Set(array2.map(({ id }) => id)),
result = array1.filter(({ id }) => set2.has(id));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can to use .some to check if array2 has an element with a given id:
const array1 = [{id: 'a'}, {id: '8'}, {id: 'c'}, {id: 'a'}];
const array2 = [{id: 'a'}, {id: 'c'}];
const res = array1.filter(({id}) => array2.some(e => e.id===id));
console.log(res);
A better way would be using a Set:
const array1 = [{id: 'a'}, {id: '8'}, {id: 'c'}, {id: 'a'}];
const array2 = [{id: 'a'}, {id: 'c'}];
const idsInArray2 = new Set(array2.map(({id}) => id));
const res = array1.filter(({id}) => idsInArray2.has(id));
console.log(res);

Two array of object merge in another array object

arr1 = [{name : xyz}, {age: 26}, {sex : m}]
arr2 = [{place: somwhere}, {std: 6}]
result should be
arr3 =[
{name : xyz, place: somwhere, std: 6},
{age: 26 , place: null , std: null},
{sex : m, place: null , std: null}
]
Try this.
You only have two data types there strings and number, you can't merge undefined data types of objects.
var arr1 = [{ name: "xyz" }, { age: 26 }, { sex: "m" }]
var arr2 = [{ place: "somwhere" }, { std: 6 }]
var arr3 = [];
arr3.push(arr1, arr2)
console.log(arr3)
Try this, return a new Array object:
Object.assign({}, arr1, arr2,arr3)
You can merge the two arrays like this:
const res = [...arr1, ...arr2]
but that will give you an array like this as result
[ {name: "xyz"}, {age: 26}, {sex: "m"}, {place: "somwhere"}, {std: 6} ]
Which is not what you want.
You could also merge one of the items from the first array with the second, like this
const res2 = arr1.map( (key, index) => [arr1[index], ...arr2])
console.log(res2)
But that will give you a result like this:
[
[ {name: "xyz"}, {place: "somwhere"}, {std: 6}],
[ {age: 26}, {place: "somwhere"}, {std: 6}],
[ {sex: "m"}, {place: "somwhere"}, {std: 6}]
]
Which is also not exactly what you wanted.
If you want to achieve exactly the result you want to, I guess you would have to have some sort of logic between the the two arrays, for instance having the values you want merged in different indexes of the second array:
const arr1 = [{name : 'xyz'}, {age: 26}, {sex : 'm'}]
const arr2 = [ [{place: 'somwhere'}, {std: 6}], [{place: null}, {std: null}], [{place:null}, {std: null}]]
const res = arr1.map( (key, index) => [arr1[index], ...arr2[index]])
console.debug('res:',res)
This gives you the exact result you want, but has a different setup. If you say more about the logic behind, there might be a better answer.
I will put the logic in java, convert it to javascript
Object[] arr1= {"benz",26,'m'};
Object[] arr2= {"somewhere",6};
Object[][] arr3= new Object[arr1.length][arr1.length];
for(int r=0;r<arr3.length;r++)
{
for(int c=0;c<1;c++)
{
if(r!=0)
System.out.println("name : "+arr1[r]+", place : "+null+", std : "+null);
else
System.out.println("name : "+arr1[r]+", place : "+arr2[c]+", std : "+arr2[c+1]);
}
}
}

how to loop over an array of object and count how many repeating values exist?

Lets say I have a list of object with different keys, one of them is name.
var resulttemp = [{name: "HYD. CYLINDER"}, {name: "pelle"}, {name: "HYD. CYLINDER"}, {name: "1212"}, {name: "pelle"}]
The final result should be:
var uniquePartNamesWithCount = [{name: "HYD. CYLINDER", count: 2}, {name: "pelle", count: 2}, {name: "1212", count: 1}]
I know how to just push unique names to an array, but how do I manage to add a counter?
One solution is to use Array.reduce() to generate an object that will hold each name and the counter related to it. Finally, you can use Object.values() to get your desired array.
var input = [
{name: "HYD. CYLINDER"},
{name: "pelle"},
{name: "HYD. CYLINDER"},
{name: "1212"},
{name: "pelle"}
];
let res = input.reduce((acc, {name}) =>
{
acc[name] = acc[name] || ({name, count: 0});
acc[name].count++;
return acc;
}, {});
console.log(Object.values(res));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
If you need the final array sorted by the counter, then you can do:
console.log( Object.values(res).sort((a, b) => b.count - a.count) );
This does what you're looking for:
// Declarations
var resulttemp = [
{name: "HYD. CYLINDER"},
{name: "pelle"},
{name: "HYD. CYLINDER"},
{name: "1212"},
{name: "pelle"}
];
const counts = {}
const uniquePartNamesWithCount = []
// Get sums
for (let obj of resulttemp){
if(counts[obj.name]){ counts[obj.name]++;}
else{counts[obj.name] = 1 }
}
// Add objects to final array
const keys = Object.keys(counts);
for(let key of keys){
let obj = {};
obj[key] = counts[key];
uniquePartNamesWithCount.push(obj);
}
// Print results
console.log(uniquePartNamesWithCount);

loop through a javascript array add the value to another array

how to loop through this array , I want to loop and and add name value to an empty array , when I console .log it gives the results below, could you please help , the result of my code is empty array
this.props.names
it shows
(3) [{…}, {…}, {…}] 0: {name: "abc", id: 1} 1: {name: "def", id: 2} 2:
{name: "gh", id: 3} length: 3
proto: Array(0)
let titles = []
let cats = []
cats = this.props.names
let len = this.props.names.length;
for( i = 0 ;i< cats.length ; i++){
titles.push(cats[i].id)
}
return titles;
from what i see... do
let titles = []
let cats = [{name: "abc", id: 1},{name: "def", id: 2},{name: "gh", id: 3}]
for( var p = 0 ;p< cats.length ; p++){
titles.push(cats[p].id)
}
console.log(titles)
If you simply want to extract the ids, and props and/or names may be empty or null, you can do it using map:
const titles = (props && props.names || []).map(val => val.id);
Here props && props.names || [] will be equal to [] if props or props.names evaluates to falsy. That way, you can still apply map to it, which will return an empty array in this case.
function demo(props) {
const titles = (props && props.names || []).map(val => val.id);
console.log(titles);
}
demo({ names: [{name: 'one', id: 1}, {name: 'two', id: 2}, {name: 'three', id: 3}] });
demo({ names: [] });
demo({});
demo(null);
See the MDN doc about the map operator.

Object.assign() and array of objects

I have a nested array like this
const names= [[{name: "John"}, {name: "Mary"}],
[{name: "Paul"}, {name: "Peter"}]];
I would like inject country into the nested object
const country = {country :"USA"}
so that output looks like
[{name: "John", country : "USA"}, {etc} ,{etc} ]
The code idea have is something like this
const combined = names.map((map)=>
Object.assign({},
country,
/*something to extract name from nested array names*/),
{country}
)
Any suggestions how i could spread the object in the nested array to form the desired output?
If the code could be improved in other ways, please let me know as well
You can use flat() to create a new array with all sub-array elements concatenated before using map() like the following way:
const names= [[{name: "John"}, {name: "Mary"}],
[{name: "Paul"}, {name: "Peter"}]];
const country = {country :"USA"}
const combined = names.flat().map(p => Object.assign(p, country));
console.log(combined);
Make use of reduce to flatten your array along with map and object.assign to add the country value to each object
const names= [[{name: "John"}, {name: "Mary"}],
[{name: "Paul"}, {name: "Peter"}]];
const country = {country :"USA"};
const newNames = names.reduce((acc, item) =>{
acc= acc.concat(item.map(value => Object.assign({}, value, country)));
return acc;
},[]);
console.log(newNames);
It's about using a nested map in an outer map:
const names = [
[{
name: "John"
}, {
name: "Mary"
}],
[{
name: "Paul"
}, {
name: "Peter"
}]
]
const country = { country: 'USA' }
const output = names.map (xs => xs.map (x => ({ ...x, ...country })))
console.log (output)
You might declare a new array literal, list country as the first item, then spread the names[0] array into it, no need for Object.assign nor .map if you only have one sub-array:
const names= [[{name: "John"}, {name: "Mary"}],
[{name: "Paul"}, {name: "Peter"}]];
const country = {country :"USA"};
const newNames = [[country, ...names[0]]];
console.log(newNames);
You can double map the names array and it's nested array and destructure country into each item.
const names = [[{name: "John"}, {name: "Mary"}],
[{name: "Paul"}, {name: "Peter"}]];
const country = {country :"USA"};
const namesWithCountry = names.map(name => name.map(n => ({...n, ...country})));
console.log(namesWithCountry);
You can use .flatMap() to flatten the arrays returned by the inner .map() method:
const names= [[{name: "John"}, {name: "Mary"}], [{name: "Paul"}, {name: "Peter"}]],
res = names.flatMap(arr => arr.map(elem => ({...elem, country: 'USA'})));
console.log(res);

Categories