Filter object based on condition - javascript

I have an object as
sports={
"cricket":true,
"football":true,
"tennis":false
}
I want to filter all the sports which are true into an array like [cricket,football]

follow above code returns keys of true value in array like [cricket,football]
const sports = {
cricket: true,
football: true,
tennis: false,
};
const result = Object.keys(sports).filter((current) => {
return sports[current];
});

Use a for...in structure:
sports={
cricket:true,
football:true,
tennis:false
}
const result = []
for(const sport in sports) {
if (sports[sport]) result.push(sport)
}
console.log(result)
more info about for...in: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

var sports_arr = Object.keys(sports);
var tmp = [];
for(var i = 0; i < sports_arr.length && sports[sports_arr[i]]; i++)
tmp.push(sports_arr[i]);

You could use Object.entries(), Array.prototype.filter() and Array.prototype.map() like so:
const sports = {
cricket:true,
football:true,
tennis:false,
};
console.log(Object.entries(sports).filter(([key, value]) => value).map(([key, value]) => key));
Object.entries() returns an array with key-value pairs:
[
['cricket', true],
['football', true],
['tennis', false],
]
You can then check the second element on each entry to filer out the ones that are false:
[
['cricket', true],
['football', true],
]
And then use map to keep only the first element:
[
'cricket',
'football',
]

As posted by #David784 in the comments, this is the simplest solution. No need to complicate it any further:
const sports = {
cricket:true,
football:true,
tennis:false,
};
const result = Object.keys(sports).filter(key => sports[key]);
console.log(result);
Merely get an array of the keys (Object.keys(sports)) and then discard the ones for which the value isn't true with a .filter().

Related

Mapping through an array to produce an object

I have an array :
[
"2022-05-20",
"2022- 06-22",
"2022-06-20"
]
and I want to produce an object like this:
{
'2022-05-20': {disabled:true},
'2022-06-22': {disabled: true},
'2022-06-20': {disabled: true},
}
I tried using a for loop but it kept producing errors. Is this possible with javascript?
You can use Array#reduce as in the following demo. You can also use Array#map but you would have to use Object.fromEntries as well.
const input = [ "2022-05-20", "2022- 06-22", "2022-06-20" ],
output = input.reduce(
(prev,cur) =>
({...prev,[cur]:{disabled:true}}), {}
);
console.log( output );
USING Array#map ...
Here is how you can use Array#map:
const input = [ "2022-05-20", "2022- 06-22", "2022-06-20" ],
output = Object.fromEntries(
input.map(date => [date, {disabled:true}])
);
console.log( output );
Can do it:
let dates = [
"2022-05-20",
"2022- 06-22",
"2022-06-20"
];
let newObj = Object.assign(...dates.map(key => ({[key]: {disabled: true}})));
console.log(newObj)
This might get the job done.
const yourArray = ["2022-05-20", "2022-06-22", "2022-06-20"];
const obj = {};
for(const x of yourArray) obj[String(x)] = { disabled: true };
console.log(obj); // :)
Create the variable obj that is going to save the produced object you want. Iterating throw your array and using a string parsed version of the value in the current iteration (parsing just in case, if you already know the array is made of strings, this is kinda unnecessary) to save it as a key on the new object, also assigning to that key, the value { disabled: true }.
Here is a one liner solution:
let res = data.reduce((acc, curr) =>(acc[curr] = {disabled: true}, acc), {});

Modify JavaScript code to use higher order functions

My below code is working fine and gives the correct desired output. But I am trying to use map, filter etc. instead of for loop. Lodash map and filter also works.
var arr = [
{"comp_id":1, desc: 'from comp1', updated: true},
{
"comp_id":2, desc: 'from comp2', updated: false}
];
var complaint_sources = [
{"comp_id":2,"consumer_source":"Hotline In","description_option":"English"},
{"comp_id":1,"consumer_source":"Online","description_option":"Other"},
{"comp_id":1,"consumer_source":"Email","description_option":null},
{"comp_id":2,"consumer_source":"Email","description_option":null}]
for(let i =0 ;i<arr.length;i++) {
let x=[];
for(let j=0;j<complaint_sources.length;j++){
if(arr[i].comp_id === complaint_sources[j].comp_id){
x.push(complaint_sources[j]);
arr[i].comp_src = x;
}
}
}
console.log(arr);
Basically I am looping through arr array and inside that looping through the complaint_sources array and when the comp_id matches I am modifying the arr array and adding a comp_src property to the object of arr array. This comp_src property will be an array of complaint_sources matched by comp_id.
this will work:
var arr = [
{"comp_id":1, desc: 'from comp1', updated: true},
{"comp_id":2, desc: 'from comp2', updated: false}
];
var complaint_sources = [
{"comp_id":2,"consumer_source":"Hotline In","description_option":"English"},
{"comp_id":1,"consumer_source":"Online","description_option":"Other"},
{"comp_id":1,"consumer_source":"Email","description_option":null},
{"comp_id":2,"consumer_source":"Email","description_option":null}
];
const grouped_sources = complaint_sources.reduce((acc, value) => {
(acc[value.comp_id] = acc[value.comp_id] || []).push(value);
return acc;
}, {})
const data = arr.map((comp) => ({
...comp,
comp_src: grouped_sources[comp.comp_id]
}));
console.log(data);

Map keys into array according to values

what's the most efficient way to map keys into array according to values based on the condition of the value?
For example, I have a map that contains the File object as the key and boolean as the value like this:
map = new Map([
[file, true],
[file1, true],
[file2, false],
[file3, true],
]);
Can I ask what's the shortcut way of creating an array of file objects if map value === true?
Intended outcome
files = [file,file1,file3];
Appreciate your help thanks!
You can use entries to get the keys and the values of the map, then filter it by whether a value (the condition) is true, and then .map to turn the [key, value] into just the key:
const map = new Map([
['file', true],
['file1', true],
['file2', false],
['file3', true],
]);
const files = [...map.entries()]
.filter(([_, cond]) => cond)
.map(([key]) => key);
console.log(files);
A simple forEach loop could do the trick here.
const map = new Map([
['test', true],
['test2', true],
['test3', false],
['test4', true],
]);
const files = [];
map.forEach((value, key, map) => {
if (value) {
files.push(key)
}
});
console.log(files);
You could use Map.entries with filter and map to achieve this. The basic idea is
Get an array of all keys/values with Map.entries
filter that array to only the entries with the value true
use map to convert from Map entries to array elements.
the code would look something like this.
map.entries().filter(entry=>entry[1]).map(entry=>entry[0]);
The answers above work but if you're after the fastest, perhaps surprisingly using a for loop is faster than the prototype Map and array methods
aka:
myMap = new Map([
["file", true],
["file1", true],
["file2", false],
["file3", true],
]);
const fastest = (files) => {
const map = [...files]
const out = []
for (let i=0; i<map.length; i++){
if (map[i][1]){
out.push(map[i][0])
}
}
return out
}
console.log(fastest(myMap))
https://coderwall.com/p/kvzbpa/don-t-use-array-foreach-use-for-instead
There are many articles and a lot of literature about this if you have a look around

Get array of keys based on values from another array

Say I have an array of objects that looks like this
let myArray = [
{item1: true},
{item2: false},
{item3: true},
{item4: false}
]
How would I iterate though this to return a new array of true values that looks like this:
let newArray = ['item1', 'item3']
I found this function but it only returns single items:
function findKey(map, term) {
var found = [];
for(var property in map) {
if(map.hasOwnProperty(property)) {
for(var key in map[property]) {
if(map[property].hasOwnProperty(key) && key === term) {
found.push(property);
}
}
}
}
return found;
}
Assuming myArray always contains objects with only 1 property.
let newArray = myArray
.map(item => Object.entries(item)[0])
.filter(([key, value]) => value)
.map(([key, value]) => key)
You could access the first key of each array item via Object.keys(), and use this to filter items with a true value for that first key, and then complete the process with a call to map() to transform the item to a value based on the same "first key" technique:
let myArray = [
{item1: true},
{item2: false},
{item3: true},
{item4: false}
]
let result = myArray
.filter(item => item[ Object.keys(item)[0] ] === true)
.map(item => Object.keys(item)[0])
console.log(result)
Use the function reduce to build the desired output. The handler of the function reduce will get the keys and check for each value === true.
This approach checks for the whole set of keys within an object. Further, this way you only use one loop.
let myArray = [{item1: true},{item2: false},{item3: true},{item4: false}],
result = myArray.reduce((a, c) => a.concat(Object.keys(c).filter(k => c[k] === true)), []);
console.log(result);
Something much optimized than the accepted answer would look like this:
const arr = [
{ item1: true },
{ item2: false },
{ item3: true },
{ item4: false }
]
const result = [];
const len = arr.length;
for (let i = 0; i < len; ++i) {
const obj = arr[i];
const key = Object.keys(obj)[0];
if(obj[key]) {
result.push(key);
}
}
console.log(result);
There is only one loop over the array, instead of map and filter which ends up looping twice.
Shortest
let newArray = myArray.map( x=>Object.keys(x)[0] ).filter( (k,i)=>myArray[i][k] );
In above solution first we use: map which works as for-loop to get array of keys (using Object.keys) ["item1", "item2", "item3", "item4"]. Then we filter that array by choose only those keys for which original array object has true. e.g myArray[0]["item1"] -> true (we use fact that filter funtion takes array element (k) and its index (i) which is the same for elements in myArray). In map and filter we use arrow functions.

merging objects in javascript

I have 2 objects array as follows:
arr1 = [ { 'v1': 'abcde',
'pv_45': 13018,
'geolocation': '17.340291,76.842807'
}]
arr2 =[{ 'v1':'abcde',
'pv_50': 13010,
geolocation: '17.340291,76.842807'
}]
I want to merge the above 2 array int0 single based on condition that 'v1' and 'geolocation' should be same as follows:
[{'v1':'abcde',
'pv_45': 13018,
'pv_50': 13010,
'geolocation': '17.340291,76.842807'}]
I used _.extend, but its not checking any condition blindly it will merge. Please share your ideas. Thanks in advance.
you can use underscore js union and uniq to do that.
var mergedArray = _.uniq(_.union(c1, c2), false, function(item, key, a){ return item; });
Using pure JavaScript it could be done like this:
var arr1 = [ { 'v1': 'abcde',
'pv_45': 13018,
'geolocation': '17.340291,76.842807'
}],
arr2 =[{ 'v1':'abcde',
'pv_50': 13010,
geolocation: '17.340291,76.842807'
}],
mergeOnV1Geo = function (arr1, arr2) {
var mergeObj = {},
merge = function (item) {
var key = item.v1 + ',' + item.geolocation;
// if this is the first object with this key
// create a new object and copy v1, geolocation info
if (!mergeObj[key]) {
mergeObj[key] = {
v1: item.v1,
geolocation: item.geolocation
};
}
// add other props
Object.keys(item).forEach(function (prop) {
if (!prop.match(/v1|geolocation/)) {
mergeObj[key][prop] = item[prop];
}
});
};
arr1.forEach(merge);
arr2.forEach(merge);
// map back into an array
return Object.keys(mergeObj).map(function (key) {
return mergeObj[key];
});
};
mergeOnV1Geo(arr1, arr2);
You could do the following:
var arr3 = [].concat.apply([], arr1, arr2);
var temp =_.groupBy(arr3, 'geolocation');
var result = Object.keys(_.groupBy(arr3, 'geolocation')).map(function(x) { return _.extend.apply(0, p[x]); })
if you prefer ES-6 arrow functions the result becomes
Object.keys(_.groupBy(arr3, 'geolocation')).map((x) => _.extend.apply(0, p[x]);)
ES6: Using spread operator and reduce.
arr1 = [{ v1: 'abcde',
pv_45: 13018,
geolocation: '17.340291,76.842807'
}]
arr2 =[{ v1:'abcde',
pv_50: 13010,
geolocation: '17.340291,76.842807'
}]
// Keys to be grouped i.e whose values should be equal
groupableKeys = ['v1', 'geolocation'];
// Reducer that creates an Object with Key as the
// groupable key values value1::value2 and Value as
// the list of objects whose v1 and geolocation are same
groupableReducer = (a, b) => {
const uniqKey = groupableKeys.map(key => b[key]).join("::");
a[uniqKey] = [...(a[uniqKey] || []), b];
return a;
}
// Merges two objects using the spread operator
mergableReducer = (a, b) => ({...a, ...b})
// Merge two arrays and start processing
groupableKeyObject = [...arr1, ...arr2].reduce(groupableReducer, {})
output = Object.keys(groupableKeyObject)
.map(key =>
groupableKeyObject[key].reduce(mergableReducer, {})
)
console.log(output);

Categories