根据2个键的属性精简数组

时间:2018-11-14 03:41:10

标签: javascript arrays object

我有一个像这样的数组。

var data = [{
  name: 'Apple',
  category: 'Fruit',
  value: 12
}, {
  name: 'Apple',
  category: 'Fruit',
  value: 20
}, {
  name: 'Orange',
  category: 'Fruit',
  value: 65
}, {
  name: 'Orange',
  category: 'Fruit',
  value: 40
}]

我需要得到一个像这样的数组:

var newData = [{
  name: 'Apple',
  category: 'Fruit',
  value: 20
}, {
  name: 'Orange',
  category: 'Fruit',
  value: 65
}]

这是数组中每个“名称”键的最大值。

这是我尝试过的:

var data = [{
  name: 'Apple',
  category: 'Fruit',
  value: 12
}, {
  name: 'Apple',
  category: 'Fruit',
  value: 20
}, {
  name: 'Orange',
  category: 'Fruit',
  value: 65
}, {
  name: 'Orange',
  category: 'Fruit',
  value: 40
}]

console.log(data.reduce(function(prev, current) {
  return (prev.name !== current.name && prev.value > current.value) ? prev : current
}))

请咨询。

4 个答案:

答案 0 :(得分:4)

您需要跟踪每个 value当前最高的name个项目,因此您可以尝试简化为一个键为{{1} } s和值是该名称当前赢得的name s。然后,获取结果对象的值:

value

(您的var data = [{ name: 'Apple', category: 'Fruit', value: 12 }, { name: 'Apple', category: 'Fruit', value: 20 }, { name: 'Orange', category: 'Fruit', value: 65 }, { name: 'Orange', category: 'Fruit', value: 40 }]; console.log(Object.values( data.reduce((a, item) => { const { name, value } = item; if (!a[name] || a[name].value < value) a[name] = item; return a; }, {}) ));方法仅在最终尝试从中取出 个项目时才有效-因为您需要更多,所以需要一个可以包含以下内容的对象多个项目。)

答案 1 :(得分:0)

使用reduce并使用findIndex检查累加器数组是否具有相同的结果。如果为-1,则在累加器数组中推送该值,否则更新该索引中的计数

var data = [{
  name: 'Apple',
  category: 'Fruit',
  value: 12
}, {
  name: 'Apple',
  category: 'Fruit',
  value: 20
}, {
  name: 'Orange',
  category: 'Fruit',
  value: 65
}, {
  name: 'Orange',
  category: 'Fruit',
  value: 40
}]



let result = data.reduce(function(acc, curr) {

  let findIfExist = acc.findIndex(elem => {
    return elem.name === curr.name;
  })
  if (findIfExist === -1) {
    acc.push(curr)
  } else {
    if (acc[findIfExist].value < curr.value) {
      acc[findIfExist].value = curr.value
    }

  }

  return acc;

}, [])

console.log(result)

答案 2 :(得分:0)

使用forEach代替reduce

var data = [{
  name: 'Apple',
  category: 'Fruit',
  value: 12
}, {
  name: 'Apple',
  category: 'Fruit',
  value: 20
}, {
  name: 'Orange',
  category: 'Fruit',
  value: 65
}, {
  name: 'Orange',
  category: 'Fruit',
  value: 40
}]

let result = {};
data.forEach(function(current) {
  if (result[current.name] &&
    result[current.name].value < current.value &&
    result[current.name].category === current.category) {
    result[current.name].value = current.value;
  } else if (!result[current.name]) {
    result[current.name] = current;
  }
});
console.log(Object.values(result));

答案 3 :(得分:0)

var data = [{
  name: 'Apple',
  category: 'Fruit',
  value: 12
}, {
  name: 'Apple',
  category: 'Fruit',
  value: 20
}, {
  name: 'Orange',
  category: 'Fruit',
  value: 65
}, {
  name: 'Orange',
  category: 'Fruit',
  value: 40
}]
let result=data.reduce(function(temp, current) {
  //check if temp has object
  var found = temp.some((el) => {
      return el.name === current.name
    });
  //if not found, add the object
    if (!found) { temp.push(current) }
  //if found and value is greater, replace the max value
  else{
    temp.find((element) => {
     if(element.name === current.name && element.value<current.value)
    element.value=current.value
    })
  }
  return temp
},[])
console.log(result);