0

Let's say I have the following object:

const myObjects = [
    { name: "Alice", age: 30 },
    { name: "Bob", age: 25 },
    { name: "Alice", age: 30 },
    { name: "David", age: 25 }
];

I wrote the following function, so that the objects with the specified same props are returned in a new array:

function findObjectsWithSameProperties(objects, property1, property2) {
  // Create an empty array to store the results
  const matchingObjects = [];

  // Loop through each object in the array
  for (const obj of objects) {
    // Check if the object has both specified properties
    if (obj.hasOwnProperty(property1) && obj.hasOwnProperty(property2)) {
      // Check if the values of the specified properties are the same
      if (obj[property1] === obj[property2]) {
        // If they are, add the object to the results array
        matchingObjects.push(obj);
      }
    }
  }

  // Return the array of matching objects
  return matchingObjects;
}

However, my function isn't returning anything when I expect it to return this:

[
    { name: "Alice", age: 30 },
    { name: "Alice", age: 30 },
];

Here's how I'm calling the function: findObjectsWithSameProperties(myObjects, "age", "name");

Does anyone know what I'm doing wrong? Here's a CodePen link: https://codepen.io/obliviga/pen/WNWNbMX?editors=0011

Edit: I updated the codepen and it works now.

4
  • 1
    if (obj[property1] === obj[property2]) is testing if the age is the same as the name. Don't you want to compare the properties of different elements, not the properties within the same element?
    – Barmar
    Commented Feb 28 at 23:26
  • Why do you post a CodePen link instead of using a Stack Snippet? Why make us go to another site when we could run the code right here?
    – Barmar
    Commented Feb 28 at 23:27
  • your function checks each single object on their own, then uses the two different property names you pass in, checks to see if that single object has both those properties, then checks if that single objects two different properties have the same values, they do not
    – matt
    Commented Feb 28 at 23:27
  • Gotcha, that makes sense. Will add an answer shortly. Commented Feb 28 at 23:30

4 Answers 4

1

You're looping through objects, checking whether the object has both props and then checking whether the name === age. Furthermore you're checking the same object's properties so you won't find duplicates either. This will obviously never be true. I suggest adding a history of the ones you've already looped through and then comparing whether it has already seen the same object or not.

function findObjectsWithSameProperties(objects, property1, property2) {
  // Create an empty array to store the results
  const matchingObjects = [];
  const seen = {};
  
  // Loop through each object in the array
  for (const obj of objects) {
    // Check if the object has both specified properties
    if (obj.hasOwnProperty(property1) && obj.hasOwnProperty(property2)) {
      const key = obj[property1] + '-' + obj[property2];
      // Check if we have seen this combination before
      if (seen[key]) {
        // Increment if it already exists
        seen[key].count++;
        // Add the object to the array of matching objects
        seen[key].objects.push(obj);
      } else {
        // If it's the first time it's ever seen this object, set count to 1
        seen[key] = { count: 1, objects: [obj] };
      }
    }
  }

  
  for (const key in seen) {
    if (seen[key].count > 1) {
      matchingObjects.push(...seen[key].objects); 
//count essentially keeps track of how many times it's already seen that object. If there has been a duplicate, it pushes the objects your matchingObjects array.
    }
  }

  // Return the array of matching objects
  return matchingObjects;
}
0

try this :

const myObjects = [
    { name: "Alice", age: 30 },
    { name: "Bob", age: 25 },
    { name: "Alice", age: 30 },
    { name: "David", age: 25 }
];

const matchingObjects = (objectsArray,...properties) => objectsArray.filter( ( mainObject,index ) => 
    objectsArray.filter( ( obj,idx ) => idx != index ).some( object => 
        properties.every( prop => mainObject[prop] == object[prop] )));

console.log(matchingObjects(myObjects,"name"));
1
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Mar 1 at 9:18
0

You can group objects by name and then filter the groups with length > 1 and flatten:

const myObjects = [
    { name: "Alice", age: 30 },
    { name: "Bob", age: 25 },
    { name: "Alice", age: 30 },
    { name: "David", age: 25 }
];

const grouped = {};
myObjects.forEach(obj => (grouped[obj.name] ??= []).push(obj))
const result = Object.values(grouped).filter(arr => arr.length > 1).flat();

console.log(result);

0

Updated my function as follows to return an array with the 2 same passed in properties:

function findObjectsWithSamePropertyValues(objects, property1, property2) {
    const result = [];
    
    for (let i = 0; i < objects.length; i++) {
        const obj1 = objects[i];
        
        for (let j = i + 1; j < objects.length; j++) {
            const obj2 = objects[j];
            
            if (obj1[property1] === obj2[property1] && obj1[property2] === obj2[property2]) {
                result.push(obj1, obj2);
            }
        }
    }
    
    return result;
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.