简体   繁体   中英

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

I've an array of objects:

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

I want to compare the objects within an array by name. If the duplicate name exists, I should compare the age and only keep the higher age object.

The expected output should be:

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

I am new to javascript/typescript and couldn't find any optimal solution for this problem. I hope, I was able to explain my problem clearly.

Thanks.

Maybe something like that

 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; }

The next provided approach uses reduce and creates in a first step just an index/map of items of highest age which are each unique by name. Thus one could use the temporary state of the programmatically built result as lookup for already existing name d items.

Within a second step one would retrieve the array of unique named items of highest age by passing such an index to 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; }

try this

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;
};

groupby

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

This works basically the same as @PeterSeliger's fine and upvote-worthy answer, except it uses a Map object which is nice because Map.set returns the Map object, allowing you to return it as the accumulator for the next iteration of the reduce function.

 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; }

Other references:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM