如何过滤对象中特定键对应的值?

时间:2018-02-21 07:05:56

标签: javascript arrays object ecmascript-6

我需要按类别分隔对象中的值,这可以从对象的键名中看到。这是对象的一部分:

const values = {
        RM1: 'Rarely',
        RM2: 'Often',
        RM3: 'Sometimes',
        RM4: 'Consistently',
        CM1: 'Rarely',
        CM2: 'Never',
        CM3: 'Sometimes',
        CM4: 'Sometimes',
        CO1: 'Often',
        CO2: 'Often',
        CO3: 'Often',
        CO4: 'Sometimes'
}

类别是RM,CM,CO等。我编写了一个过滤掉类别的函数(answersvalues所属的较大对象):

const categorizeAnswers = (answers) =>{
  const valueNames = Object.keys(answers.values);
  const values = Object.values(answers.values);
  const getCategoryList = category => valueNames.filter(value => {
    return value.includes(category);
  })
  const RM = getCategoryList("RM");
  const CM = getCategoryList("CM");
  const CO = getCategoryList("CO");
}

但现在我不确定如何获得与这些类别相对应的值。因此,对于RM,我想要一个类似:['Rarely', 'Often', 'Sometimes', 'Consistently']的数组。同样适用于其他类别。

有什么想法吗?我觉得这很简单,我错过了一些明显的东西。

6 个答案:

答案 0 :(得分:2)

您可以简单地在类别数组上使用map来获取数组,如下所示:

const RM = getCategoryList("RM").map((key) => answers.values[key]);

答案 1 :(得分:1)

您可以根据属性名称的非数字部分动态生成类别,然后将它们添加到一个 reduce 调用中的初始空对象中。这样,类别不是硬编码的(但需要符合相同的命名模式):

var values = {
        RM1: 'Rarely',
        RM2: 'Often',
        RM3: 'Sometimes',
        RM4: 'Consistently',
        CM1: 'Rarely',
        CM2: 'Never',
        CM3: 'Sometimes',
        CM4: 'Sometimes',
        CO1: 'Often',
        CO2: 'Often',
        CO3: 'Often',
        CO4: 'Sometimes'
}

function getCategories(data) {
  return Object.keys(data).reduce(function(acc, key){
    var p = key.replace(/\d+/,'');
    acc[p]? acc[p].push(data[key]) : acc[p] = [data[key]];
    return acc;
  }, Object.create(null));
}

console.log(getCategories(values));

答案 2 :(得分:0)

  

有什么想法吗?我觉得这很简单,我很想念   显而易见的事。

您使用了错误的变量valuesNames,将其valueNames设为您之前使用相同方法初始化的<{p}}

var categorizeAnswers = (answers) =>{
  const valueNames = Object.keys(answers.values);
  const values = Object.values(answers.values);
  const getCategoryList = category => valueNames.filter(value => { //notice the change from valuesNames to valueNames 
    return value.includes(category);
  })

  const RM = getCategoryList("RM");
  console.log(RM);
  const CM = getCategoryList("CM");
  const CO = getCategoryList("CO");
}

此外,就像"RM1".includes("RM") true一样,"ARM1".includes("RM")也是true

使用indexOf

  const getCategoryList = category => valueNames.filter(value => { 
    return value.indexOf(category) == 0;
  })

答案 3 :(得分:0)

您可以使用String#startsWith查看并使用Set获取uniuque值

const getCategoryList = category =>
        [...new Set(valuesNames.filter(v => v.startsWith(category))];

答案 4 :(得分:0)

使用for..in来迭代对象&amp; indexOf检查密钥名称是否包含传递的字符串

var values = {
  RM1: 'Rarely',
  RM2: 'Often',
  RM3: 'Sometimes',
  RM4: 'Consistently',
  CM1: 'Rarely',
  CM2: 'Never',
  CM3: 'Sometimes',
  CM4: 'Sometimes',
  CO1: 'Often',
  CO2: 'Often',
  CO3: 'Often',
  CO4: 'Sometimes'
}

function getValues(keyName) {
  var valArray = [];
  for (let keys in values) {
    if (keys.indexOf(keyName) !== -1 && valArray.indexOf(values[keys]) === -1) {
      valArray.push(values[keys])

    }

  }
  return valArray;
}
console.log(getValues('CO'))

答案 5 :(得分:0)

这是使用ES5的一个非常紧凑的解决方案。

const getCategoryList = (category) => {
  const categories = [].concat(Object.keys(answers.values).filter((value) => value.includes(category)));
  const values = [].concat(categories.map((value) => answers.values[value]));
  return [categories, values]
}

const [ categories, values ] = getCategoryList('RM');
console.log(categories, values)