Looking to remove an array item from the nested array if subset array have value a null or 0(zero) using lodash. I tried filter but I am looking for best way in term of performance.
const arr = [["a","b","c"],["f","r","p",0],["r",22,null,"t"],["d","e","f"]];
console.log("arr", arr);
// output should be [["a","b","c"],["d","e","f"]]
You can use filter() and some()
const arr = [["a","b","c"],["f","r","p",0],["r",22,null,"t"],["d","e","f"]];
let res = arr.filter(x => !x.some(a => a === null || a === 0))
console.log(res)
With lodash : filter and includes functions:
const arr = [["a","b","c"],["f","r","p",0],["r",22,null,"t"],["d","e","f"]];
const result = _.filter(arr, x => !_.includes(x, null) && !_.includes(x, 0))
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.14/lodash.min.js"></script>
With ES6 : filter and some functions:
const arr = [["a","b","c"],["f","r","p",0],["r",22,null,"t"],["d","e","f"]];
const result = arr.filter( x => !x.some(s => s === null || s === 0))
console.log(result)
With ES6 : reduce:
const arr = [["a","b","c"],["f","r","p",0],["r",22,null,"t"],["d","e","f"]];
const result = arr.reduce( (acc, c) => {
if(c.some(x => x === null || x === 0)) {
return acc
}
return [...acc, c]
},[])
console.log(result)
//cost will not let modify the variable
let arr = [["a","b","c"],["f","r","p",0],["r",22,null,"t"],["d","e","f"]];
arr = arr.filter(aItem=>{
//compact will remove null, 0 , undefined values from array item
return aItem.length===_.compact(aItem).length;
});
console.log("...arr",arr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.14/lodash.core.min.js"></script>
You can try with filter() and some().
Please Note: The following solution will also work for other falsy inputs like "" and undefined.
Using Lodash:
const arr = [["a","b","c"],["f","r","p",0],["r",22,null,"t"],["d","e","f"],["d",undefined,"f"],["d","e","f",""]];
var res = _.filter(arr, a => !a.some(i => !i));
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.14/lodash.core.min.js" integrity="sha256-NAQPwApfC7Ky1Y54LjXf7UrUQFbkmBEPFh/7F7Zbew4=" crossorigin="anonymous"></script>
Using Vanilla JS:
const arr = [["a","b","c"],["f","r","p",0],["r",22,null,"t"],["d","e","f"],["d",undefined,"f"],["d","e","f",""]];
var res = arr.filter(a => !a.some(i => !i));
console.log(res);
Related
I have a set of values (groups) in a comma delimited string and would like to check if any of those values match any array items (reqRights) and return true or false, but is returns undefined error.
const reqRights = ["18900253","3217840","1053"];
const groups = "3217635,18272308,1053,3217633,18900253,3217698,3217699,3217840,10162510";
function checker(value) {
var groups = groups.split(",");
console.log(groups);
return groups.every(function(v) {
return value.indexOf(v) !== -1;
});
}
arr = reqRights.filter(checker);
console.log(arr);
js engine SpiderMonkey 1.8, does not support .includes and some methods
You're using const on groups, so you cannot reassign it. And you also should move groups.split(",") outside of checker function to avoid creating a new array every time calling checker.
some can help you to check regRights item is in groups instead of every.
const reqRights = ["18900253","3217840","1053"];
const groups = "3217635,18272308,1053,3217633,18900253,3217698,3217699,3217840,10162510";
const groupsArray = groups.split(",");
function checkGroupValue(group) {
return group === value;
}
function checker(value) {
return groupsArray.some(checkGroupValue);
}
arr = reqRights.filter(checker);
console.log(arr);
const reqRights = ["18900253","3217840","1053"];
const groupsConstant = "3217635,18272308,1053,3217633,18900253,3217698,3217699,3217840,10162510";
function checker(value) {
var groups = groupsConstant.split(",");
return groups.every(v => groups.indexOf(v) !== -1);
}
arr = reqRights.filter(checker);
console.log('elements matched: ', arr.length ? 'yes' : 'no');
I was trying to avoid the indexOf as it might give a false positive result (example: reqRight "1053" would be listed if found in "1053568")
THis is not necessarily the shortest way, but should be compatible with spiderMonkey 1.8
const reqRights = ["18900253","3217840","1053"];
const groups = "3217635,18272308,1053,3217633,18900253,3217698,3217699,3217840,10162510";
function checker(values, required) {
var valuesArray = values.split(",");
return valuesArray.filter((value) => {
return required.filter((req) => {
return req === value;
}).length > 0;
})
}
arr = checker(groups, reqRights);
console.log(arr);
Use Array.find in filtering from groups:
const reqRights = ["18900253","3217840","1053"];
const groups = "3217635,18272308,1053,3217633,18900253,3217698,3217699,3217840,10162510";
const checker = value =>
({[value]: reqRights.find(v => value === v) ? true : false});
const checked = groups.split(`,`).map(checker);
console.log(checked);
Or maybe concat both (groups as array) arrays, sort that numerically and filter the result on double values.
const reqRights = ["18900253","3217840","1053"];
const groups = "3217635,18272308,1053,3217633,18900253,3217698,3217699,3217840,10162510";
const checked = groups.split(`,`)
.concat(reqRights)
.sort( (a, b) => +a - +b)
.filter((v, i, self) => self[i+1] === v);
console.log(checked);
You can simply achieve this by using Array.map() along with Array.some() method.
Live Demo :
const reqRights = ["18900253","3217840","1053"];
const groups = "3217635,18272308,1053,3217633,18900253,3217698,3217699,3217840,10162510";
const res = groups.split(',').map(item => {
return reqRights.some(n => item === n)
});
console.log(res);
I have problem with delete all duplicate in array.
Array = [1,1,2,2,3]
Every solution, what I found, haves result this
Array = [1,2,3]
But I need this
Array = [3]
How can I do this?
You can first iterate over the array once to obtain a Map of the frequencies of each item and then filter to find the elements that only appeared once.
const arr = [1,1,2,2,3];
const freq = arr.reduce((acc,curr)=>(acc.set(curr,(acc.get(curr)||0)+1),acc),new Map);
const res = arr.filter(x => freq.get(x) === 1);
console.log(res);
You could store an object for occurences of each element and get the elements that have the occurence of 1
const arr = [1, 1, 2, 2, 3]
const occurrences = arr.reduce((acc, el) => {
acc[el] = (acc[el] || 0) + 1
return acc
}, {})
const res = Object.entries(occurrences)
.filter(([el, time]) => time === 1)
.map(([el]) => +el)
console.log(res)
Unlike some of the other solutions, this allows you to make a single loop over the array, rather than a reduce followed by a filter and/or map loop. That said, there are trade-offs in readability and other condition checks, and it plays a bit fast and loose with the semantic intention of a reduce, so it might be a wash in terms of benefits.
const myArray = [1,1,2,2,3];
const dupesRemoved = myArray.reduce((acc, cur, idx, src) => {
if (!acc.dupes.has(cur)) {
if (acc.singleInstances.has(cur)) {
acc.singleInstances.delete(cur);
acc.dupes.add(cur);
} else {
acc.singleInstances.add(cur);
}
}
if (idx === src.length - 1) {
return [...acc.singleInstances];
}
return acc;
}, { singleInstances: new Set(), dupes: new Set() });
console.log(dupesRemoved);
Here is a simple and short solution:
let arr = [1,1,2,2,3];
let filtered_arr = arr.filter(v => arr.indexOf(v) === arr.lastIndexOf(v));
console.log(filtered_arr);
I have an array like:
let arr = ['ABC', 'DEF']
And I'd like to transform that array to
let obj = {"ABC": 0, "DEF": 0}
What's the appropriate ES6 syntax to make that transformation?
let arr = ['ABC', 'DEF']
arr.reduce(x => ({[x] : 0 }))
This is close but I end up with {"ABC": 0}
Basically, I want to take an array of arbitrary length and assign all of the values in that array to a "default" value of 0.
Thanks!
Just use a plain, simple loop:
const arr = ['ABC', 'DEF'];
const obj = {};
for (const x of arr) obj[x] = 0;
If you want to get fancy, I'd recommend Object.fromEntries:
Object.fromEntries(arr.map(x => [x, 0]))
You are just making single objects like map. You need to keep returning the object.
const arr = ['ABC', 'DEF']
const result = arr.reduce((o, k) => ({[k] : 0, ...o }), {});
console.log(result)
const result2 = arr.reduce((o, k) => (o[k] = 0, o), {});
console.log(result2)
obj = arr.reduce((result, item, index) => {
result[item] = 0
return result
}, {})
Hopefully, this will help you. let me know if you have any issues.
You can just use Array.reduce and pass an empty object as the initial value like code below:
var arr = ["ABC","DEF"].reduce((a,b)=> (a[b]=0,a),{});
console.log(arr);
This question already has answers here:
Completely removing duplicate items from an array
(11 answers)
Closed 3 years ago.
I have a question in Javascript.
This is the following Array: [1,0,0,0,0,0,0]
I would like to return the only value that does not repeat, that is, 1.
Any suggestions?
I have this:
var result = arr.filter(x => arr.indexOf(x) !== 0);
Using indexOf and lastIndexOf
You can compare indexOf and lastIndexOf and filter()
let arr = [1,0,0,0,0,0,0];
let res = arr.filter(x => arr.indexOf(x) === arr.lastIndexOf(x));
console.log(res)
If you only want the first element you can use find()
let arr = [1,0,0,0,0,0,0];
let res = arr.find(x => arr.indexOf(x) === arr.lastIndexOf(x));
console.log(res)
You can remove duplicates using Set() and then use filter() on it.
let arr = [1,0,0,0,0,0,0];
let res = [...new Set(arr)].filter(x => arr.indexOf(x) === arr.lastIndexOf(x));
console.log(res)
Using nested filter()
let arr = [1,0,0,0,0,0,0];
let res = arr.filter(x => arr.filter(a => a === x).length === 1);
console.log(res)
Using Object and reduce()
This one is best regarding time complexity.
let arr = [1,0,0,0,0,0,0];
let obj = arr.reduce((ac,a) => (ac[a] = ac[a] + 1 || 1,ac),{});
let res = Object.keys(obj).filter(x => obj[x] === 1).map(x => +x || x);
console.log(res)
I have two arrays , I want to find the item in Arr1 with Arr2 Keys and map the value of arr2 to arr1 if not found value should be 0.
const Arr1=['A','B','C']
const Arr2=[{key:'a',val:100},{key:'c',val:100}]
Expected Result:
const Arr3=[{key:'a',val:100},{key:'b',val:0},{key:'c',val:100}]
You could use map and find like this:
const Arr1=['A','B','C']
const Arr2=[{key:'a',val:100},{key:'c',val:100}]
const Arr3 = Arr1.map(c => {
const exists = Arr2.find(b => b.key === c.toLowerCase());
return exists || { key: c.toLowerCase(), val: 0 };
})
console.log(Arr3)
Or using reduce like this:
const Arr1=['A','B','C']
const Arr2=[{key:'a',val:100},{key:'c',val:100}]
const Arr3 = Arr1.reduce((r, a) => {
const exists = Arr2.find(b => b.key === a.toLowerCase());
const item = exists || { key: a.toLowerCase(), val: 0 }
return r.concat(item)
},[])
console.log(Arr3)
In context to you previous question you can still return a value if you want and convert keys to lowercase before compare.
const Arr1=['a','b','c']
var Arr2=[{key:'a',val:100},{key:'c',val:100}]
Arr2.map(val => {
if(Arr1.indexOf(val.key) >= 0 )
val.val = val
else
val = 0
})