json - Javascript reduce() on an Object - Stack Overflow

I have a javascript object below:let filters = {numbers: {'0': 'is_no_selected',&#

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()?

Share Improve this question asked Aug 13, 2021 at 2:14 settingsetting 651 silver badge6 bronze badges 1
  • in general, I guess you could convert object to Array then reduce – Bravo Commented Aug 13, 2021 at 2:28
Add a ment  | 

9 Answers 9

Reset to default 1

You 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

相关推荐

  • json - Javascript reduce() on an Object - Stack Overflow

    I have a javascript object below:let filters = {numbers: {'0': 'is_no_selected',&#

    7小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信