Mam tablicę obiektów, która wygląda mniej więcej tak:

let products = [
    {
      "id": 7,
      "name": "product 1",
      "description": "description product 1",
      "images": [
        {
          "id": 1,
          "path": "image1-product1.jpeg",
        },
        {
          "id": 2,
          "path": "image2-product1.jpeg",
        }
      ]
     },
     {
      "id": 20,
      "name": "product 2",
      "description": "description product 2",
      "images": [
        {
          "id": 3,
          "path": "image1-product2.jpeg",
        },
        {
          "id": 4,
          "path": "image2-product2.jpeg",
        }
      ]
     }
  ]

Każdy produkt ma tablicę zdjęć, muszę porównać ten układ zdjęć z takim, który otrzymam jako parametr i który będzie wyglądał dokładnie tak, jak jeden z nich, aby wiedzieć, do którego produktu należy i zwrócić ten produkt. na przykład, jeśli otrzymam tę tablicę:

[
  {
    "id": 3,
    "path": "image1-product2.jpeg",
  },
  {
    "id": 4,
    "path": "image2-product2.jpeg",
  }
]

Równa się tablicy obrazów produktu 2, więc jak mogę je porównać i zwrócić ten produkt?

1
FeRcHo 2 kwiecień 2020, 23:16

3 odpowiedzi

Najlepsza odpowiedź

Jeśli porównanie według id jest wystarczające, użyj Array.prototype.every() jest dużo bardziej wydajne niż użycie JSON.stringify():

const productHasImages = images => product => (
  product.images.length === images.length &&
  product.images.every(
    (image, i) => image.id === images[i].id
  )
);

const products = [{ id: 7, name: 'product 1', description: 'description product 1', images: [{ id: 1, path: 'image1-product1.jpeg' }, { id: 2, path: 'image2-product1.jpeg' }] }, { id: 20, name: 'product 2', description: 'description product 2', images: [{ id: 3, path: 'image1-product2.jpeg' }, { id: 4, path: 'image2-product2.jpeg' }] }];
const images = [{ id: 3, path: 'image1-product2.jpeg' }, { id: 4, path: 'image2-product2.jpeg' }];

const product = products.find(productHasImages(images));
console.log(product);

Jeśli chcesz dopasować bez względu na kolejność i musisz porównać wiele właściwości, musisz być nieco sprytniejszy, inicjując Map wpisane przez id w zamknięciu:

const productHasImages = images => {
  const map = new Map(
    images.map(image => [image.id, image])
  );

  return product => (
    product.images.length === images.length &&
    product.images.every(
      ({ id, path }) => {
        const image = map.get(id);

        if (!image) return false;

        // compare other properties here
        return image.path === path;
      }
    )
  );
};

const products = [{ id: 7, name: 'product 1', description: 'description product 1', images: [{ id: 1, path: 'image1-product1.jpeg' }, { id: 2, path: 'image2-product1.jpeg' }] }, { id: 20, name: 'product 2', description: 'description product 2', images: [{ id: 3, path: 'image1-product2.jpeg' }, { id: 4, path: 'image2-product2.jpeg' }] }];
// in different order
const images = [{ id: 4, path: 'image2-product2.jpeg' }, { id: 3, path: 'image1-product2.jpeg' }];

const product = products.find(productHasImages(images));
console.log(product);
2
Patrick Roberts 2 kwiecień 2020, 20:54

Jeśli dobrze zrozumiałem. Otrzymasz obiekt zawierający identyfikator i obraz. Ten obiekt znajduje się gdzieś w jednym ze zdjęć produktów i chcesz znaleźć / zwrócić produkt, który zawiera to zdjęcie?

Jeśli tak, możesz połączyć prototyp tablicy .find, aby znaleźć obiekt spełniający warunek (jeden z obrazów jest tym, który podasz)

let products = [{
    "id": 7,
    "name": "product 1",
    "description": "description product 1",
    "images": [{
        "id": 1,
        "path": "image1-product1.jpeg",
      },
      {
        "id": 2,
        "path": "image2-product1.jpeg",
      }
    ]
  },
  {
    "id": 20,
    "name": "product 2",
    "description": "description product 2",
    "images": [{
        "id": 3,
        "path": "image1-product2.jpeg",
      },
      {
        "id": 4,
        "path": "image2-product2.jpeg",
      }
    ]
  }
]


const compare = (imageObjToFind) => {
  return products.find(product => product.images.find(image => JSON.stringify(image) === JSON.stringify(imageObjToFind)))
}

const IwantToCompareThis = {
  "id": 4,
  "path": "image2-product2.jpeg",
}

console.log(compare(IwantToCompareThis))
0
Sølve Tornøe 2 kwiecień 2020, 20:24

Jeśli kolejność nie ma znaczenia i można założyć, że wszystkie identyfikatory i ścieżki są zgodne i muszą być dokładne ... Następnie możesz po prostu porównać stringify każdej tablicy. Jeśli potrzebujesz bardziej swobodnego porównania, musisz jeszcze bardziej zapętlić tablice i porównać poszczególne wartości.

let products = [
  {
    "id": 7,
    "name": "product 1",
    "description": "description product 1",
    "images": [
      {
        "id": 1,
        "path": "image1-product1.jpeg",
      },
      {
        "id": 2,
        "path": "image2-product1.jpeg",
      }
    ]
   },
   {
    "id": 20,
    "name": "product 2",
    "description": "description product 2",
    "images": [
      {
        "id": 3,
        "path": "image1-product2.jpeg",
      },
      {
        "id": 4,
        "path": "image2-product2.jpeg",
      }
    ]
   }
]

let incoming = [
  {
    "id": 3,
    "path": "image1-product2.jpeg",
  },
  {
    "id": 4,
    "path": "image2-product2.jpeg",
  }
]

let result = null
result = products.find(product => {
  return JSON.stringify(product.images) === JSON.stringify(incoming)
})

console.log(result)
2
ageoff 2 kwiecień 2020, 20:24