I have a javascript object below:
let filters = {
numbers: {
'0': 'is_no_selected',
'1': 'is_one_selected',
'2': 'is_two_selected',
'3': 'is_three_selected',
'4': 'is_four_selected',
'5': 'is_five_selected',
},
words: {
please: 'is_please_selected',
help: 'is_help_selected',
me: 'is_me_selected',
},
}
And I got two input:'numbers'
and ['4','5']
I want to get:
{
numbers: {
'is_no_selected': false,
'is_one_selected': false,
'is_two_selected': false,
'is_three_selected': false,
'is_four_selected': true,
'is_five_selected': true,
}
}
And when I input other two input:'words'
and ['please']
I want to get:
{
words: {
'is_please_selected': true,
'is_help_selected': false,
'is_me_selected': false,
}
}
How to make this happen using reduce()
?
I have a javascript object below:
let filters = {
numbers: {
'0': 'is_no_selected',
'1': 'is_one_selected',
'2': 'is_two_selected',
'3': 'is_three_selected',
'4': 'is_four_selected',
'5': 'is_five_selected',
},
words: {
please: 'is_please_selected',
help: 'is_help_selected',
me: 'is_me_selected',
},
}
And I got two input:'numbers'
and ['4','5']
I want to get:
{
numbers: {
'is_no_selected': false,
'is_one_selected': false,
'is_two_selected': false,
'is_three_selected': false,
'is_four_selected': true,
'is_five_selected': true,
}
}
And when I input other two input:'words'
and ['please']
I want to get:
{
words: {
'is_please_selected': true,
'is_help_selected': false,
'is_me_selected': false,
}
}
How to make this happen using reduce()
?
- in general, I guess you could convert object to Array then reduce – Bravo Commented Aug 13, 2021 at 2:28
9 Answers
Reset to default 1You need to get the entries of the object before using reduce
:
let filters = {
numbers: {
'0': 'is_no_selected',
'1': 'is_one_selected',
'2': 'is_two_selected',
'3': 'is_three_selected',
'4': 'is_four_selected',
'5': 'is_five_selected',
},
words: {
please: 'is_please_selected',
help: 'is_help_selected',
me: 'is_me_selected',
},
}
function fn(obj, filterKey, filters) {
filters = filters.map(x => ''+x); // convert all filters to strings (keys are always string)
return Object
.keys(obj)
.filter(x => x === filterKey) // only the selected property
.map(x => obj[x]) // get the object
.map(x => {
return Object.entries(x).reduce((out, curr) => {
const [key, val] = curr;
out[val] = filters.includes(key);
return out;
}, {})
});
}
console.log(fn(filters, 'numbers', [0]))
I'd do something like below
const process = function (data, key, input) {
const result = Object.keys(data[key])
.reduce((acc, index) => {
const isValid = input.includes(index);
if(isValid)
acc[data[key][index]] = true;
else
acc[data[key][index]] = false;
return acc;
}, {});
return {
[key] : result
}
};
var filters = {
numbers: {
'0': 'is_no_selected',
'1': 'is_one_selected',
'2': 'is_two_selected',
'3': 'is_three_selected',
'4': 'is_four_selected',
'5': 'is_five_selected',
},
words: {
please: 'is_please_selected',
help: 'is_help_selected',
me: 'is_me_selected',
},
};
// client code: process(filters, 'numbers', ['4', '5']));
For me the simplest is to bine the inputs into an object with the same numbers and words keys.
Then iterate the Object.entries()
and match the numbers/words keys between input and filter objects
let filters={numbers:{0:"is_no_selected",1:"is_one_selected",2:"is_two_selected",3:"is_three_selected",4:"is_four_selected",5:"is_five_selected"},words:{please:"is_please_selected",help:"is_help_selected",me:"is_me_selected"}};
const inputs = {
numbers: ['4', '5'],
words: ['please'],
};
const res = {};
Object.entries(filters).forEach(([key,o])=>{
const fil = res[key] = {};
Object.entries(o).forEach(([k,v]) => fil[v] = inputs[key].includes(k));
})
console.log(res)
Here you go. Not how I would have done it, but if you must use reduce, you can do it like this.
let filters = {
numbers: {
'0': 'is_no_selected',
'1': 'is_one_selected',
'2': 'is_two_selected',
'3': 'is_three_selected',
'4': 'is_four_selected',
'5': 'is_five_selected',
},
words: {
please: 'is_please_selected',
help: 'is_help_selected',
me: 'is_me_selected',
},
}
var numbers = filter(filters, 'numbers', ['4', '5']);
var words = filter(filters, 'words', ['please']);
console.log(numbers);
console.log(words);
function filter(filter_obj, key, input) {
return {
[key]: Object.keys(filters[key]).reduce((a, c) => {
a[filters[key][c]] = input.includes(c)
return a;
}, {})
}
}
Using two reduce()
for filtering the inner object and the outer object.
/* input is the data and filtering key and value list */
function filter (data, key, vals) {
// inner filter
const filterValues = (obj, values) => Object.keys(obj).reduce((accum, ele) => {
accum[obj[ele]] = values.includes(ele);
return accum;
}, {});
// outer filter
const filteredKey = Object.keys(data).reduce((accum, ele) => {
if (ele === key)
accum[key] = data[key];
return accum;
}, {});
// call outer filter first then pass it to inner filter
return {
[key]: filterValues(filteredKey[key], vals)
};
}
Call it with the data you gave in the firs argument as:
console.log(filter(data, 'numbers', ['4', '5']));
console.log(filter(data, 'words', ['please']));
Here is the plete code you can test and run.
const data = {
numbers: {
'0': 'is_no_selected',
'1': 'is_one_selected',
'2': 'is_two_selected',
'3': 'is_three_selected',
'4': 'is_four_selected',
'5': 'is_five_selected',
},
words: {
please: 'is_please_selected',
help: 'is_help_selected',
me: 'is_me_selected',
},
}
/* input is data and filtering key and value list */
function filter (data, key, vals) {
// inner filter
const filterValues = (obj, values) => Object.keys(obj).reduce((accum, ele) => {
accum[obj[ele]] = values.includes(ele);
return accum;
}, {});
// outer filter
const filteredKey = Object.keys(data).reduce((accum, ele) => {
if (ele === key)
accum[key] = data[key];
return accum;
}, {});
// call outer filter first then pass it to inner filter
return {
[key]: filterValues(filteredKey[key], vals)
};
}
console.log(filter(data, 'numbers', ['4', '5']));
console.log(filter(data, 'words', ['please']));
Sure, very simple one line code
let filters = {
numbers: {
'0': 'is_no_selected',
'1': 'is_one_selected',
'2': 'is_two_selected',
'3': 'is_three_selected',
'4': 'is_four_selected',
'5': 'is_five_selected',
},
words: {
please: 'is_please_selected',
help: 'is_help_selected',
me: 'is_me_selected',
},
}
const fn=(f,a)=>({[f]:Object.entries(filters[f]).reduce((r,[k,v])=>(r[v]=a.includes(k),r),{})});
console.log(fn('numbers', ['4','5']))
console.log(fn('words',['please']))
A Basic solution:
function filter(all_option, select_key, select_option) {
let ret = {};
let s_f = all_option[select_key];
for (let k in s_f) {
if (select_option.includes(k)) {
ret[s_f[k]] = true;
} else {
ret[s_f[k]] = false;
}
}
return ret;
}
convert it to map reduce version:
function filter(all_option, select_key, select_option) {
let ret = {};
let s_f = all_option[select_key];
Object.keys(s_f).map(k => {
if (select_option.includes(k)) {
ret[s_f[k]] = true;
} else {
ret[s_f[k]] = false;
}
});
return ret;
}
this way...
const filters =
{ numbers:
{ '0': 'is_no_selected'
, '1': 'is_one_selected'
, '2': 'is_two_selected'
, '3': 'is_three_selected'
, '4': 'is_four_selected'
, '5': 'is_five_selected'
}
, words:
{ please: 'is_please_selected'
, help: 'is_help_selected'
, me: 'is_me_selected'
}
}
const foo = (in1,in2) =>
Object.entries(filters[ in1 ])
.reduce((r,[k,v]) => Object.assign(r,{[v]:in2.includes(k)}), {})
console.log('a;', foo('numbers', ['4','5']) )
console.log('b;', foo('words', ['please']) )
.as-console-wrapper { max-height: 100% !important; top: 0 }
You can reduce your numbers
and words
objects by reducing their Object.entries() which returns an array
of an object's own enumerable property [key, value]
pairs.
let filters = {
numbers: {
'0': 'is_no_selected',
'1': 'is_one_selected',
'2': 'is_two_selected',
'3': 'is_three_selected',
'4': 'is_four_selected',
'5': 'is_five_selected',
},
words: {
please: 'is_please_selected',
help: 'is_help_selected',
me: 'is_me_selected',
},
};
let reduceFilter = function(filters, name, input) {
return Object.entries(filters[name]).reduce((acc, [key, value]) => {
acc[name][value] = input.includes(key);
return acc;
}, {[name]: {}});
};
console.log(reduceFilter(filters, 'numbers', ['4', '5']));
console.log(reduceFilter(filters, 'words', ['please']));
Notice that both the reducer function expressions make use of destructing assignments above to break apart the [key, value]
pairs easily.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742329292a4423384.html
评论列表(0条)