Перебор вложенного списка в Angular [закрыто]

avatar
Billy
1 июля 2021 в 15:55
100
4
0

Объект JSON

const users = [{
"name":"Mark",
"age":30,
"isActive" : true,
"cars":{ Owned : ["Ford", "BMW", "Fiat"], Rented : ["Ford", "BMW", "Fiat"]}
},{
"name":"Mistry",
"age":30,
"isActive" : true,
"cars":{ Owned : ["Ford", "BMW", "Fiat"], Rented : ["Ford", "BMW", "Fiat"]}
},{
"name":"John",
"age":30,
"isActive" : false,
"cars":{ Owned : ["Ford", "BMW", "Fiat"], Rented : ["Ford", "BMW", "Fiat"]}
}];

Мой подход:

Машинопись

let rentedCars:any[]=[];
let ownedCars:any[]=[];
for (let i = 0; i < users.length; i++) {
  const cars = users[0].cars;
  for (let i = 0; i < cars.Owned.length; i++) {
    ownedCars.push(cars.Owned[i]);
  }
for (let j = 0; j < cars.Rented.length; j++) {
    rentedCars.push(cars.Rented[j]);
  }
}

Попытка добавить весь список арендованных и собственных автомобилей в отдельный список. Приведенный выше код работает, но есть ли более эффективный способ сделать это.

Источник

Ответы (4)

avatar
Rob Bailey
1 июля 2021 в 16:11
1

Вы можете сделать это с помощью Array.reduce. Например,

let cars = { rentedCars: [], ownedCars: [] };
users.reduce((acc, curr) => { 
  acc.rentedCars = acc.rentedCars.concat(curr.cars.Rented);
  acc.ownedCars = acc.ownedCars.concat(curr.cars.Owned);
  return acc;
}, cars);

Я не проверял это, но думаю, что это даст что-то похожее на то, к чему вы стремитесь.

avatar
Parameshwar Rao
1 июля 2021 в 16:58
1

Решение с использованием карты, сокращения и объединения в плоский массив

  1. map для цикла (дает массив массивов)

  2. уменьшить, чтобы получить одно значение (уменьшить массив)

  3. объединить totalcars с currentcar (плоский массив)

    rentedCars: any[] = []; ownedCars: any[] = [];

separate() {
    
    this.rentedCars = this.users.map(x => x.cars.Rented).reduce((totalcars,currentcar)=>{
     return totalcars.concat(currentcar);
    },[]);
    
    
    this.ownedCars = this.users.map(x => x.cars.Owned).reduce((totalcars,currentcar)=>{
      return totalcars.concat(currentcar);
     },[]);    
  }

Еще проще

Вы сопоставляете получение массива массива, а затем напрямую используете метод Array.prototype.flat() (представленный в ES2019) для выравнивания массивов, хотя он доступен только в Node.js, начиная с версии 11, и совсем не в Internet Explorer.

separate() {
this.rentedCars = this.users.map(x => x.cars.Rented).flat(1);
this.ownedCars = this.users.map(x => x.cars.Owned).flat(1);
}
avatar
Tanuwo
1 июля 2021 в 16:16
1

Вот мое решение.

rentedCars = users.reduce((array,user)=>{
    return [...array,...user.cars.Rented]
},[])

ownedCars = users.reduce((array,user)=>{
    return [...array,...user.cars.Owned]
},[])

если вы хотите удалить повторяющиеся элементы

rentedCars= [...new Set(rentedCars)];
ownedCars= [...new Set(ownedCars)];
avatar
ilphrine
1 июля 2021 в 16:14
1

В качестве первой идеи я должен предложить что-то вроде этого:

let rentedCars: Set<any> = new Set();
let ownedCars: Set<any> = new Set();
users.forEach((user) => {
  user.cars.Owned.forEach((ownedCar) => ownedCars.add(ownedCar));
  user.cars.Rented.forEach((rentedCar) => rentedCars.add(rentedCar));
});

он использует функцию forEach, которая сокращает код, но я также использовал Set для удаления дубликата вашего списка