比较数组中的对象并创建一个没有重复的新数组

Compare objects within an array and create a new array without duplicates

我有一个对象数组:

[
  { name: "John", age: "34" },
  { name: "Ace", age: "14" },
  { name: "John", age: "45" },
  { name: "Harry", age: "11" },
]

我想按名称比较数组中的对象。如果存在重名,我应该比较年龄,只保留年龄较大的对象。

预期的输出应该是:

[
  { name: "Ace", age: "14" },
  { name: "John", age: "45" },
  { name: "Harry", age: "11" },
]

我是 javascript/typescript 的新手,找不到解决此问题的任何最佳解决方案。我希望,我能够清楚地解释我的问题。

谢谢。

也许是这样

const obj = [{ name: "John", age: "34" }, { name: "Ace", age: "14" }, { name: "John", age: "45" }, { name: "Harry", age: "11" }];
const objCopy = JSON.parse(JSON.stringify(obj))

const res = objCopy.reduce((acc, obj) => {
  const personExist = acc.find(({ name }) => name === obj.name);
  if (personExist) {
    if (parseInt(obj.age, 10) > parseInt(personExist.age, 10)) {
        personExist.age = obj.age;
    }
  } else {
    acc.push(obj);
  }
  return acc;
}, []);

console.log({ res });
.as-console-wrapper { min-height: 100%!important; top: 0; }

下一个提供的方法使用 reduce 并在第一步中仅创建一个 index/map 最高年龄的项目,每个项目的名称都是唯一的。因此,可以使用以编程方式构建的 result 的临时状态来查找已经存在的 named 项。

在第二步中,通过将这样的索引传递给 Object.values.

来检索年龄最大的唯一命名项目的数组

function collectHighestAgeItemOfSameName(result, item) {
  const { name, age } = item;
  if (
    !(name in result) ||
    Number(result[name].age) < Number(age)
  ) {
    result[name] = item;
  }
  return result;
}

const sampleData = [{
  name: "John",
  age: "34"
}, {
  name: "Ace",
  age: "14"
}, {
  name: "Harry",
  age: "9"
}, {
  name: "John",
  age: "45"
}, {
  name: "Harry",
  age: "11"
}, {
  name: "Ace",
  age: "13"
}];

console.log(
  'reduced index of unique person items of highest age ...',
  sampleData
    .reduce(collectHighestAgeItemOfSameName, {})
)
console.log(
  'array of unique person items of highest age ...',
  Object
    .values(
      sampleData
        .reduce(collectHighestAgeItemOfSameName, {})
    )
)
.as-console-wrapper { min-height: 100%!important; top: 0; }

试试这个

var objArr=...your json object;
var maxValueGroup = "name";
var maxValueName = "age";
console.log(JSON.stringify(newArr(objArr,maxValueGroup, maxValueName)));

newArr

var newArr = function (objArr,maxValueGroup, maxValueName) {
  var arr = groupBy(objArr, maxValueGroup);
  var newArr = [];
  $.each(arr, function (key) {
    var maxVal = 0;
    var maxValItem;
    arr[key].forEach((element) => {
      if (element[maxValueName] > maxVal) {
        maxVal = element[maxValueName];
        maxValItem = element;
      }
    });
    newArr.push(maxValItem);
  });
  return newArr;
};

分组

var groupBy = function (xs, key) {
  return xs.reduce(function (rv, x) {
    (rv[x[key]] = rv[x[key]] || []).push(x);
    return rv;
  }, {});
};

这与@PeterSeliger 的 fine 和 upvote-worthy 答案基本相同,除了它使用 Map object which is nice because Map.set returns Map 对象,允许您 return 它作为 reduce 函数下一次迭代的累加器。

const data = [{name: "John", age: "34"}, {name: "Ace", age: "14"}, {name: "John", age: "45"}, {name: "Harry", age: "11"}];

const res = [...data.reduce(
  (acc, val) =>
    +(acc.get(val.name)?.age ?? -1) >= +val.age ?
      acc :
      acc.set(val.name, val),
  new Map()
).values()];

console.log(JSON.stringify( res ));
.as-console-wrapper { min-height: 100%!important; top: 0; }

其他参考资料:

  1. Unary plus (+)
  2. Optional chaining (?.)
  3. Nullish coalescing operator (??)
  4. Conditional (ternary) operator
  5. Array.prototype.reduce()
  6. Spread syntax (...)