当两个对象具有相同的键时,如何根据另一个对象中给出的标准对来自对象的数据进行分类?

How to classify data from object according to criteria given in another object, when the two objects have same keys?

我有两个对象需要以某种方式组合以实现所需的输出。这是一个玩具示例。

假设我正在 运行 一项关于新小鼠饮食的实验。我收集了 6 只老鼠,给它们每只喂食不同的食物。几周后,我给所有老鼠称重并记录每只老鼠的体重。这些权重在以下对象中给出:

const postExperimentWeights = {
  mickey: 20,
  minnie: 11,
  jerry: 15,
  stuart: 33,
  gonzales: 17,
  pinky: 50,
};

为了得出节食是否成功的结论,我有另一个数据对象,其目标体重将被视为 中等,或 good,每只鼠标。

const targetWeights = {
  mickey: {
    belowIsBad: 15,
    aboveIsGood: 22,
  },
  minnie: {
    belowIsBad: 5,
    aboveIsGood: 10,
  },
  jerry: {
    belowIsBad: 16,
    aboveIsGood: 20,
  },
  stuart: {
    belowIsBad: 30,
    aboveIsGood: 40,
  },
  gonzales: {
    belowIsBad: 10,
    aboveIsGood: 15,
  },
  pinky: {
    belowIsBad: 60,
    aboveIsGood: 100,
  },
};

我想要的输出是 3 个变量,每个变量都包含一个名称数组:

const good = ['minnie', 'gonzales']; // those were above their respective `aboveIsGood`
const mediocre = ['mickey', 'stuart']; // were between respective `belowIsBad` & `aboveIsGood`
const bad = ['jerry', 'pinky']; // below respective `belowIsBad`

是否有一种相当简单或优雅的方法来实现所需的输出?我通常更喜欢使用函数式方法,但无论如何都会感谢您的帮助。

将它们一个接一个地循环并推入正确的数组中。

const postExperimentWeights = {
  mickey: 20,
  minnie: 11,
  jerry: 15,
  stuart: 33,
  gonzales: 17,
  pinky: 50,
};

good = []
bad = []
mediocre = []


const targetWeights = {
  mickey: {
    belowIsBad: 15,
    aboveIsGood: 22,
  },
  minnie: {
    belowIsBad: 5,
    aboveIsGood: 10,
  },
  jerry: {
    belowIsBad: 16,
    aboveIsGood: 20,
  },
  stuart: {
    belowIsBad: 30,
    aboveIsGood: 40,
  },
  gonzales: {
    belowIsBad: 10,
    aboveIsGood: 15,
  },
  pinky: {
    belowIsBad: 60,
    aboveIsGood: 100,
  },
};

for (mouse in postExperimentWeights) {
 let value = postExperimentWeights[mouse]
 if (value < targetWeights[mouse]["belowIsBad"]) {
    bad.push(mouse)
    continue
 }
 
  if (value > targetWeights[mouse]["aboveIsGood"]) {
    good.push(mouse)
    continue
    
 }
 
 mediocre.push(mouse)
 
}

console.log(good,bad,mediocre)

您可以使用array reduce

因此,根据您的数据,您可以执行以下操作:

代码注释说明

// object.entries will create a paired key-value 
// array of array i.e. [['mickey',20],['minnie', 11, <and so on>]]
Object.entries(postExperimentWeights).reduce(([prev, curr]) => {
  // key for the property name (person name), and its value.
  const [key, value]  = curr;

  // if it doesn't exist on the weigt, return skip? (you decide)
  if (targetWeights) {
    return prev;
  }

  if (targetWeights.belowIsBad < value) {
    // store it in its respective key based on condition
    return {
      bad: prev.bad.concat(key);
      ...prev,
    }
  }

  if (targetWeights.aboveIsGood > value) {
    // store it in its respective key based on condition
    return {
      good: prev.bad.concat(key);
      ...prev,
    }
  }
  
  // since this one is neither of the conditions above, its a mediocre 
  return {
      mediocre : prev.bad.concat(key);
      ...prev,
    }
}, {
  good: [],
  mediocre : [],
  bad: []
});

我将使用 Object.entries() 迭代实验结果并与目标值进行简单比较:

const postExperimentWeights = {
  mickey: 20,
  minnie: 11,
  jerry: 15,
  stuart: 33,
  gonzales: 17,
  pinky: 50,
};

const targetWeights = {
  mickey: {
    belowIsBad: 15,
    aboveIsGood: 22,
  },
  minnie: {
    belowIsBad: 5,
    aboveIsGood: 10,
  },
  jerry: {
    belowIsBad: 16,
    aboveIsGood: 20,
  },
  stuart: {
    belowIsBad: 30,
    aboveIsGood: 40,
  },
  gonzales: {
    belowIsBad: 10,
    aboveIsGood: 15,
  },
  pinky: {
    belowIsBad: 60,
    aboveIsGood: 100,
  },
};

function evaluateResults(input, target) {
 const good = [];
 const avg = [];
 const bad = [];
 for(const [key,value] of Object.entries(input)) {
   if(value < target[key].belowIsBad) {
    bad.push(key);
   }else if(value > target[key].aboveIsGood) {
    good.push(key);
   }else {
    avg.push(key);
   }
 }
  console.log("good:", good);
  console.log("avg:", avg);
  console.log("bad:", bad);
}

evaluateResults(postExperimentWeights,targetWeights);

另一个使用reduce的解决方案使用push而不是concat

const postExperimentWeights = {mickey: 20,minnie: 11,jerry: 15,stuart: 33,gonzales: 17,pinky: 50,};
const targetWeights = {  mickey: {belowIsBad: 15,aboveIsGood: 22,},minnie: {belowIsBad: 5,aboveIsGood: 10,},jerry: {belowIsBad: 16,aboveIsGood: 20,},stuart: {belowIsBad: 30,aboveIsGood: 40,},gonzales: {belowIsBad: 10,aboveIsGood: 15,},pinky: {belowIsBad: 60,aboveIsGood: 100,},};

let res = Object.entries(postExperimentWeights).reduce((acc, [mouse,weight]) => {
    if (weight > targetWeights[mouse].aboveIsGood) acc.good.push(mouse)
    else if (targetWeights[mouse].belowIsBad < weight && weight <targetWeights[mouse].aboveIsGood) acc.mediocre.push(mouse)
    else if (targetWeights[mouse].belowIsBad > weight) acc.bad.push(mouse)
    return acc
}, {good: [],mediocre: [],bad: []})

console.log(res)

你可以用最简单的术语来使用这段代码

const mices = {
  mickey: 20,
  minnie: 11,
  jerry: 15,
  stuart: 33,
  gonzales: 17,
  pinky: 50
};

const targetWeights = {
  mickey: {
    belowIsBad: 15,
    aboveIsGood: 22
  },
  minnie: {
    belowIsBad: 5,
    aboveIsGood: 10
  },
  jerry: {
    belowIsBad: 16,
    aboveIsGood: 20
  },
  stuart: {
    belowIsBad: 30,
    aboveIsGood: 40
  },
  gonzales: {
    belowIsBad: 10,
    aboveIsGood: 15
  },
  pinky: {
    belowIsBad: 60,
    aboveIsGood: 100
  }
};

function findTheWeights(main, target) {
  const good = [];
  const mediocre = [];
  const bad = [];
  for (let mice in main) {
    const { belowIsBad, aboveIsGood } = target[mice];

    main[mice] > aboveIsGood
      ? good.push(mice)
      : main[mice] < belowIsBad
      ? bad.push(mice)
      : mediocre.push(mice);
  }

  return { good, bad, mediocre };
}

console.log(findTheWeights(mices, targetWeights));