Js Filter nested array - javascript

Here is the code
let nestedArray = [[1,2], [3,4], [5,6,7], [8,9,10]]
let arr = [2,3,6,7]
I want nestedArray filter all element equal arr element, then return
result = [[2],[3],[6,7]]
Here is my solution, it won't work.
arr.forEach(id => {
let result = nestedArray.filter(nest => {
return nest.filter(item => item === id)
})
Each time it only output a single match

let nestedArray = [[1,2], [3,4], [5,6,7], [8,9,10]]
let arr = [2,3,6,7]
let result = nestedArray.map(array =>
array.filter(item => arr.includes(item))
).filter((a) => a.length);
console.log(result)

nestedArray.map(
na=>na.filter(
num=>arr.includes(num)
)
).filter(
na=>na.length!==0
)

Related

How to match duplicate values in nested arrays in JS

I have an array which contains nested arrays that are dynamically created, it looks like this:
[['1', '2'],['1','3', '4'],['1', '3']]
I am trying to implement AND logic by getting only duplicate values from these arrays. My expected output here would be ['1'] since all nested arrays must contain the same value.
// [['1', '2'],['1','3', '4'],['1', '3']]
const arrays = [...new Set(response)].filter(newSet => newSet.length > 0);
const builder = []; // array of all the id's no longer needed
// [[],[],[]]
arrays.forEach(arr => {
// []
arr.forEach(value => {
// [[], [], []]
const found = arrays.filter(a => a.find(v => v === value));
if (found.length === 0)
builder.push(value);
});
});
console.log(builder); // empty []
This gives me an empty array because of the filter(). How could I return an array of values that all (3 in this case but could be more) arrays contain?
Expected output with the above input would be ["1"]. Any help appreciated.
from what I understand you need the common elements from all array
let response1 = [['1', '2'],['1','3', '4'],['1', '3']]
let response2 = [['1', '2', '3'],['1','3', '4'],['1', '3']]
const getCommon = res => [...new Set(res.flat())].filter(a => res.every(c => c.includes(a)));
console.log(getCommon(response1))
console.log(getCommon(response2))
UPDATE
Apparently the set transformation is unnecessary since anyway it has to give the elements common to every array so filtering from res[0] should do
let response1 = [['1', '2'],['1','3', '4'],['1', '3']]
let response2 = [['1', '2', '3'],['1','3', '4'],['1', '3']]
const getCommon = res => res[0].filter(a => res.every(c => c.includes(a)));
console.log(getCommon(response1))
console.log(getCommon(response2))
You can make a count object that has the frequency of each number in it, and just check if the frequency of a number is equal to the length of the original array.
const getIntersectVals = (arrayOfVals)=>{
const freqs = {};
for(let arr of arrayOfVals){
for(let val of arr){
if(freqs[val]) freqs[val]++;
else freqs[val] = 1;
}
}
const uniqueVals = Object.keys(freqs);
const correctVals = uniqueVals.filter(elem=>{
return freqs[elem] === arrayOfVals.length;
})
return correctVals;
}
const arrayOfVals = [['1', '2'],['1','3', '4'],['1', '3']];
console.log(getIntersectVals(arrayOfVals))
Lodash intesection if you don't mind
const arrayOfVals = [['1', '2'],['1','3', '4'],['1', '3']];
const result = _.intersection(...arrayOfVals);
console.log(result);
.as-console-wrapper{min-height: 100%!important; top: 0}
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js"></script>

Flatten An array element wise in JavaScript

I have two Arrays which look like this:
array1: [["abc","def","ghi"],["jkl","mno","pqr"]],
array2: [[1,2,3,4,5],[6,7,8,9,10]]
I want to operate a Flattening operation which gives me result like this: Flatten(array1,array2):
result: [["abc","def","ghi",1,2,3,4,5],["jkl","mno","pqr",6,7,8,9,10]]
Any suggestions on the same?
Edit 1: Both the Arrays always have the same length.
You can use map() on one of them and concat() it with corresponding element of other array
Note: I am considering length of both the arrays will be equal
const arr1 = [["abc","def","ghi"],["jkl","mno","pqr"]];
const arr2 = [[1,2,3,4,5],[6,7,8,9,10]];
const flattern = (a1, a2) => a1.map((x, i) => x.concat(a2[i]))
console.log(flattern(arr1, arr2))
If lengths of arrays are not same then you will have to first find the larger array and then map over it.
const arr1 = [["abc","def","ghi"],["jkl","mno","pqr"], ['a','b','c']];
const arr2 = [[1,2,3,4,5],[6,7,8,9,10]];
const flattern = (a1, a2) =>{
if(a1.length === a2.length){
return a1.map((x, i) => x.concat(a2[i]))
}
else if(a1.length > a2.length){
return a1.map((x, i) => x.concat(a2[i] || []))
}
else{
return a2.map((x, i) => x.concat(a1[i] || []))
}
}
console.log(flattern(arr1, arr2))
Since the length of the array is same, you could use map() over one array and concat the other.
const array1 = [["abc","def","ghi"],["jkl","mno","pqr"]];
const array2 = [[1,2,3,4,5],[6,7,8,9,10]];
let result = array1.map((a, i) => a.concat(array2[i]));
console.log(result);
You can use [...].flat(), see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat

I want to remove duplicated values in side an array and get unique value

for example look at this array, I want to remove those objects which the the value of their "age" is the same.
var array =[
{age:21,name:"sam",class="C"},
{age:24,name:"david",class="f"},
{age:45,name:"zack",class="f"},
{age:21,name:"jeff",class="g"},
{age:21,name:"marco",class="a"},
{age:26,name:"john",class="d"},
];
I want to get this result:
[
{age:21,name:"sam",class="C"},
{age:24,name:"david",class="f"},
{age:45,name:"zack",class="f"},
{age:26,name:"john",class="d"},
];
You can use reduce
var array = [
{age:21,name:"sam",class:"C"},
{age:24,name:"david",class:"f"},
{age:45,name:"zack",class:"f"},
{age:21,name:"jeff",class:"g"},
{age:21,name:"marco",class:"a"},
{age:26,name:"john",class:"d"}
];
let result = array.reduce((a,v) => {
let i = a.findIndex(person => person.age === v.age);
if(i !== -1){
return a;
}
return [...a, {...v}];
},[]);
console.log(result);
You can do this
var array =[
{age:21,name:"sam",class:"C"},
{age:24,name:"david",class:"f"},
{age:45,name:"zack",class:"f"},
{age:21,name:"jeff",class:"g"},
{age:21,name:"marco",class:"a"},
{age:26,name:"john",class:"d"},
];
var res = array.filter((i, index, self) => self.findIndex(k => k.age === i.age)==index);
console.log(res);
//Another clever way with lesser complexity :)
var res = array.reduce((a,v)=>{
if(!a[v.age]){
a[v.age] = v
};
return a
},{})
console.log(Object.values(res))

How to connect an item of an array with another item of an array

I have two array:
let array1 = ["aaa","bbb"];
let array2 = ["f1","f2","f3"];
How can I get the following result?
aaa f1, aaa f2, aaa f3, bbb f1, bbb f2, bbb f3
let array1 = ["aaa", "bbb"];
let array2 = ["f1", "f2", "f3"];
const newArray = [];
array1.forEach(item1 => {
array2.forEach(item2 => {
newArray.push(item1 + " " + item2)
})
})
console.log(newArray);
Here's a solution using Array.prototype.flatMap() and Array.prototype.map():
const array1 = ["aaa","bbb"];
const array2 = ["f1","f2","f3"];
const result = array1.flatMap(v1 => array2.map(v2 => `${v1} ${v2}`));
console.log(result);
let array1 = ["aaa", "bbb" ];
let array2 = ["f1","f2","f3"];
let response=[];
array1.forEach( ele1 => {
array2.forEach( ele2=> {
response.push( ele1 +' '+ ele2 );
})
});
console.log( response );
'use strict';
let array1 = ["aaa","bbb"];
let array2 = ["f1","f2","f3"];
let res = [];
array1.forEach( a1 => array2.forEach(a2 => res.push([`${a1} ${a2}`])) );
let array1 = ["aaa","bbb"];
let array2 = ["f1","f2","f3"];
let array3 = []
for (ele1 of array1) {
for (ele2 of array2) {
array3.push(ele1 + ' ' + ele2);
}
}
You could use reduce() and map() to achieve required result by using with Spread_syntax.
Please check below code snippet:
let array1 = ["aaa","bbb"],
array2 = ["f1","f2","f3"];
let result = array1.reduce((r,v)=>[...r,array2.map(m=>`${v} ${m}`).join(',')],[])
console.log(result.join(','))
With Loop
let array1 = ["aaa","bbb"];
let array2 = ["f1","f2","f3"];
let temp =[];
let index=0;
for(let i=0;i<array1.length;i++) {
for(let j=0;j<array2.length;j++) {
temp[index] = `${array1[i]} ${array2[j]}`;
index++;
}
}
console.log(temp);
With For Each
array1.forEach(item1 => {
array2.forEach(item2 => {
tempNew.push(item1 + " " + item2)
})
})
console.log(tempNew);
JSFiddle Fiddle
You can use Array.prototype.reduce() combined with Array.prototype.map(), spread syntax and template literals
Code:
const array1 = ["aaa", "bbb"];
const array2 = ["f1", "f2", "f3"];
const result = array1.reduce((a, c) => [...a, ...array2.map(f => `${c} ${f}`)], []);
console.log(result);

JS filtering array using regexp on value

I have arr with categories tree. Example: category yy is subcategory of ww and ww is subcategory of zz. I want to filter this array and get this output: ['aa_bb', 'aa_cc', 'zz_ww_yy']. So I don't want zz and zz_ww becouse i have this in zz_ww_yy. I think that I must use filter function and maybe some regexp? hmmm and maybe foreach? What you think?
var arr = ['aa_bb', 'aa_cc', 'aa', 'zz', 'zz_ww','zz_ww_yy'];
var filtered = arr.filter(function(a){
//???
})
console.log(filtered);
You could take String#indexOf and filter the temporary result array with the given string.
Then check if the string is not a substring of the result set and push it if not.
var array = ['aa_bb', 'aa_cc', 'aa', 'zz', 'zz_ww','zz_ww_yy'],
result = array.reduce(function (r, a) {
r = r.filter(b => a.indexOf(b) === -1);
if (r.every(b => b.indexOf(a) === -1)) {
r.push(a);
}
return r;
}, []);
console.log(result);
try that on also, you could easely change the logic.
var arr = ['aa_bb', 'aa_cc', 'aa', 'zz', 'zz_ww', 'zz_ww_yy'];
function shoulFilterCategory(arr, itemToTest, itemIndex) {
var shouldFilter = false;
arr.filter((item, index) => index !== itemIndex)
.forEach(item => {
if (item.startsWith(itemToTest) && itemToTest.length < item.length) {
shouldFilter = true;
}
});
return shouldFilter;
}
var filtered = arr.filter(
(item, index) => !shoulFilterCategory(arr, item, index)
);
console.log('filtered', filtered);

Categories