Фильтрация массива объектов по конкретному свойству

Необходима помощь в фильтрации массива объектов.

На входе имеем массив, который получаем в ответ на запрос к серверу, например:

let arr = [
  { id: 0, streetName: '30 лет Победы', streetId: 0, addressId: 0, building: '1', flat: '1' },
  { id: 2, streetName: '30 лет Победы', streetId: 0, addressId: 1, building: '1', flat: '2' },
  { id: 2, streetName: '30 лет Победы', streetId: 0, addressId: 2, building: '1', flat: '3' },
  { id: 1, streetName: 'Ленина', streetId: 1, addressId: 3, building: '15', flat: '7' },
  { id: 1, streetName: 'Ленина', streetId: 1, addressId: 4, building: '15', flat: '9' },
  { id: 1, streetName: 'Ленина', streetId: 1, addressId: 5, building: '15', flat: '10' },
  { id: 3, streetName: 'Советская', streetId: 2, addressId: 6, building: '40', flat: '2' },
  { id: 3, streetName: 'Советская', streetId: 2, addressId: 7, building: '40', flat: '7' },
  { id: 3, streetName: 'Советская', streetId: 2, addressId: 8, building: '40', flat: '9' },
  { id: 4, streetName: 'Мира', streetId: 3, addressId: 9, building: '5', flat: '3' },
  { id: 4, streetName: 'Мира', streetId: 3, addressId: 10, building: '5', flat: '4' },
  { id: 4, streetName: 'Мира', streetId: 3, addressId: 11, building: '5', flat: '5' },
];

Далее, я отрисовываю его на странице с помощью реакт

return (
  <div>
    {housingStock.map((hs, index) => {
      return <li key={`${hs}_${index}`}>{hs.streetName}</li>;
    })}
  </div>);

В итоге у меня выводится список с повторяющимися значениями из свойства streetName

введите сюда описание изображения

Мне необходимо отфильтровать массив так, чтобы если значение из свойства streetName, при его повторе отрисовывалось лишь один раз. Подскажите, пожалуйста, как это правильно сделать.

Я понимаю, что необходимо пройтись по массиву, например, методом map, но что дальше делать никак не могу выразить в коде


Ответы (2 шт):

Автор решения: Darth

let arr = [
  { id: 0, streetName: '30 лет Победы', streetId: 0, addressId: 0, building: '1', flat: '1' },
  { id: 2, streetName: '30 лет Победы', streetId: 0, addressId: 1, building: '1', flat: '2' },
  { id: 2, streetName: '30 лет Победы', streetId: 0, addressId: 2, building: '1', flat: '3' },
  { id: 1, streetName: 'Ленина', streetId: 1, addressId: 3, building: '15', flat: '7' },
  { id: 1, streetName: 'Ленина', streetId: 1, addressId: 4, building: '15', flat: '9' },
  { id: 1, streetName: 'Ленина', streetId: 1, addressId: 5, building: '15', flat: '10' },
  { id: 3, streetName: 'Советская', streetId: 2, addressId: 6, building: '40', flat: '2' },
  { id: 3, streetName: 'Советская', streetId: 2, addressId: 7, building: '40', flat: '7' },
  { id: 3, streetName: 'Советская', streetId: 2, addressId: 8, building: '40', flat: '9' },
  { id: 4, streetName: 'Мира', streetId: 3, addressId: 9, building: '5', flat: '3' },
  { id: 4, streetName: 'Мира', streetId: 3, addressId: 10, building: '5', flat: '4' },
  { id: 4, streetName: 'Мира', streetId: 3, addressId: 11, building: '5', flat: '5' },
];

console.log(
arr.reduce((arr, el) => 
  ((arr.find(({streetName}) => el.streetName == streetName) || arr.push(el)), arr)
, [])
)

→ Ссылка
Автор решения: yar85

Можно использовать промежуточный объект Set для избавления от дубликатов (передав в конструктор массив названий улиц):

return (
  <ul>
    {[...new Set(housingStock.map(hs => hs.streetName))].map(
      sn => (<li key={sn}>{sn}</li>)
    )}
  </ul>
);

Насколько я понимаю реактъ, подклеивать числовой индекс к названию в значении key тут не нужно (потому что каждое название улицы в результате будет уникальным).

let arr = [
  { id: 0, streetName: '30 лет Победы', streetId: 0, addressId: 0, building: '1', flat: '1' },
  { id: 2, streetName: '30 лет Победы', streetId: 0, addressId: 1, building: '1', flat: '2' },
  { id: 2, streetName: '30 лет Победы', streetId: 0, addressId: 2, building: '1', flat: '3' },
  { id: 1, streetName: 'Ленина', streetId: 1, addressId: 3, building: '15', flat: '7' },
  { id: 1, streetName: 'Ленина', streetId: 1, addressId: 4, building: '15', flat: '9' },
  { id: 1, streetName: 'Ленина', streetId: 1, addressId: 5, building: '15', flat: '10' },
  { id: 3, streetName: 'Советская', streetId: 2, addressId: 6, building: '40', flat: '2' },
  { id: 3, streetName: 'Советская', streetId: 2, addressId: 7, building: '40', flat: '7' },
  { id: 3, streetName: 'Советская', streetId: 2, addressId: 8, building: '40', flat: '9' },
  { id: 4, streetName: 'Мира', streetId: 3, addressId: 9, building: '5', flat: '3' },
  { id: 4, streetName: 'Мира', streetId: 3, addressId: 10, building: '5', flat: '4' },
  { id: 4, streetName: 'Мира', streetId: 3, addressId: 11, building: '5', flat: '5' },
];

const result = [...new Set(arr.map(hs => hs.streetName))];
console.log(result);

const e = React.createElement;
ReactDOM.render(
  e('ul', null,
    ...[...new Set(arr.map(hs => hs.streetName))].map(
      sn => e('li', { key: sn }, sn)
    )
  ),
  document.getElementById('?')
);
<div id="?"><div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

→ Ссылка