Построить требуемый массив объектов, используя Filter и Reduce - PullRequest
0 голосов
/ 06 мая 2019

У меня есть следующие примеры данных, которые представляют собой три массива объектов, а именно:

let dets = [
  {
    "id": 1,
    "name":"tom",
    "country":"USA",
    "phone": "1234"
  },
  {
    "id": 2,
    "name":"sarah",
    "country":"ITALY",
    "phone": "8899"
  },
  {
    "id": 3,
    "name":"harry",
    "country":"GERMANY",
    "phone": "3434"
  }  
];

let foods = [
  {
    "id": 1,
    "food":"pizza"
  },
  {
    "id": 1,
    "name":"pasta"
  },
  {
    "id": 1,
    "name":"oranges"
  },  
  {
    "id": 2,
    "name":"donuts"
  },  
  {
    "id": 2,
    "name":"pizza"
  },
  {
    "id": 2,
    "name":"apples"
  },
  {
    "id": 3,
    "name":"apples"
  },
  {
    "id": 3,
    "name":"strawberries"
  }
];

let musics = [
  {
    "id": 1,
    "music":"jazz"
  },
  {
    "id": 1,
    "music":"funk"
  },
  {
    "id": 1,
    "music":"country"
  },  
  {
    "id": 2,
    "music":"jazz"
  },  
  {
    "id": 2,
    "music":"rock"
  },
  {
    "id": 2,
    "music":"heavy metal"
  },
  {
    "id": 3,
    "music":"orchestral"
  },
  {
    "id": 3,
    "music":"jazz"
  },
  {
    "id": 3,
    "music":"percussion"
  }  
];

Конечный результат, которого я хотел бы достичь, - это следующий массив результатов объектов на основе приведенных выше данных, гдеи еда, и музыка - это массивы внутри объекта.

Я понимаю, что могу использовать простые итерации массива для достижения приведенного ниже результата, но мне хотелось посмотреть, можно ли это сделать лучше, используя JavaScript фильтр и уменьшение .

Массив dets является родительским массивом и, используя значение "id", извлекает значения дочернего массива как в foods, так и * 1014.*.

let result = [
  {
    "id": 1,
    "name":"tom",
    "country":"USA",
    "phone": "1234",
    "foods": ["pizza","pasta","oranges"],
    "musics": ["jazz","funk","country"]
  },
  {
    "id": 2,
    "name":"sarah",
    "country":"ITALY",
    "phone": "8899",
    "foods": ["donuts","pizza","apples"],
    "musics": ["jazz","rock","heavy metal"]
  },
  {
    "id": 3,
    "name":"harry",
    "country":"GERMANY",
    "phone": "3434",
    "foods": ["apples","strawberries"],
    "musics": ["orchestral","jazz","percussion"]    
  }
];

Ответы [ 3 ]

3 голосов
/ 06 мая 2019

Вы можете использовать map для цикла по dets массиву.Вы можете использовать reduce чтобы получить музыку и еду, соответствующие идентификатору.(Вы можете использовать filter, но для этого потребуется еще один цикл для получения свойства name / music).

Вы можете использовать оператор распространения для поверхностного копирования исходного объекта.

let dets = [{"id":1,"name":"tom","country":"USA","phone":"1234"},{"id":2,"name":"sarah","country":"ITALY","phone":"8899"},{"id":3,"name":"harry","country":"GERMANY","phone":"3434"}];
let foods = [{"id":1,"name":"pizza"},{"id":1,"name":"pasta"},{"id":1,"name":"oranges"},{"id":2,"name":"donuts"},{"id":2,"name":"pizza"},{"id":2,"name":"apples"},{"id":3,"name":"apples"},{"id":3,"name":"strawberries"}];
let musics = [{"id":1,"music":"jazz"},{"id":1,"music":"funk"},{"id":1,"music":"country"},{"id":2,"music":"jazz"},{"id":2,"music":"rock"},{"id":2,"music":"heavy metal"},{"id":3,"music":"orchestral"},{"id":3,"music":"jazz"},{"id":3,"music":"percussion"}];

let result = dets.map(o => {
  return {
    ...o,
    foods: foods.reduce((c, v) => v.id === o.id ? c.concat(v.name) : c, []),
    musics: musics.reduce((c, v) => v.id === o.id ? c.concat(v.music) : c, []),
  }
});

console.log(result);

Другим вариантом является переменная карты продуктов и музыки.Это для уменьшения петель.

let dets = [{"id":1,"name":"tom","country":"USA","phone":"1234"},{"id":2,"name":"sarah","country":"ITALY","phone":"8899"},{"id":3,"name":"harry","country":"GERMANY","phone":"3434"}];
let foods = [{"id":1,"name":"pizza"},{"id":1,"name":"pasta"},{"id":1,"name":"oranges"},{"id":2,"name":"donuts"},{"id":2,"name":"pizza"},{"id":2,"name":"apples"},{"id":3,"name":"apples"},{"id":3,"name":"strawberries"}];
let musics = [{"id":1,"music":"jazz"},{"id":1,"music":"funk"},{"id":1,"music":"country"},{"id":2,"music":"jazz"},{"id":2,"music":"rock"},{"id":2,"music":"heavy metal"},{"id":3,"music":"orchestral"},{"id":3,"music":"jazz"},{"id":3,"music":"percussion"}];

//Summarize the foods and music first
let foodsMap = foods.reduce((c, v) => (c[v.id] = (c[v.id] || []).concat(v.name), c), {});
let musicsMap = musics.reduce((c, v) => (c[v.id] = (c[v.id] || []).concat(v.music), c), {});

let result = dets.map(o => {
  return {
    ...o,
    foods: foodsMap[o.id] || [],
    musics: musicsMap[o.id] || [],
  }
});


console.log(result);
0 голосов
/ 06 мая 2019

    let dets = [{"id": 1,"name":"tom","country":"USA","phone": "1234"}, 
    {"id": 2,"name":"sarah","country":"ITALY","phone": "8899"},
    {"id": 3,"name":"harry","country":"GERMANY","phone": "3434"}];
    let foods = [{"id": 1,"name":"pizza"},
    {"id": 1,"name":"pasta"},
    {"id": 1,"name":"oranges"},  
    {"id": 2,"name":"donuts"},  
    {"id": 2,"name":"pizza"},
    {"id": 2,"name":"apples"},
    {"id": 3,"name":"apples"},
    {"id": 3,"name":"strawberries"}];
    let musics = [{"id": 1,"music":"jazz"},
    {"id": 1,"music":"funk"},
    {"id": 1,"music":"country"},  
    {"id": 2,"music":"jazz"},  
    {"id": 2,"music":"rock"},
    {"id": 2,"music":"heavy metal"},
    {"id": 3,"music":"orchestral"},
    {"id": 3,"music":"jazz"},
    {"id": 3,"music":"percussion"}];
    let output = dets.map((det)=>{
        det.foods = foods.filter((food)=>{
            return det.id === food.id;
        }).map((food)=>{
        return food.name;
        });
        det.musics = musics.filter((music)=>{
            return music.id === det.id;
        }).map((music)=>{
        return music.music;
        });
        return det;
    });
    console.log(output);
0 голосов
/ 06 мая 2019

Вы можете использовать идентификатор объекта Map и заполнить его всеми значениями:

  const idMap = new Map();
  const get = id => idMap.get(id) || (obj => (idMap.set(id, obj), obj))({});

  for(const info of dets)
    Object.assign(get(info.id), info);

 for(const { food, id } of foods) {
    const user = get(id);
    (user.foods || (user.foods = []).push(food);
 }

  //...

  const result = [...idMap.values()];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...