Формирование JSON с ключом и значением, если ключ существует - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть структура JSON что-то вроде:

    [  
   {  
      "name":"angelinas"
   },
   {  
      "name":"besuto"
   },
   {  
      "name":"catch",
      "cuisine":"Japanese"
   },
   {  
      "name":"center cut"
   },
   {  
      "name":"fedora"
   },
   {  
      "name":"Habanero",
      "cuisine":"Mexican"
   },
   {  
      "name":"Indies"
   },
   {  
      "name":"new"
   },
   {  
      "name":"RazINN"
   },
   {  
      "name":"restaurantTestVenue779"
   },
   {  
      "name":"restaurantTestVenue9703"
   },
   {  
      "name":"Salsa ",
      "cuisine":"Mexican"
   },
   {  
      "name":"Sushi Place",
      "cuisine":"Japanese"
   },
   {  
      "name":"The Ashoka"
   },
   {  
      "name":"The Poboys"
   },
   {  
      "name":"the shogun"
   },
   {  
      "name":"vinyard view"
   }
]

Используя JSON выше, я хочу определить, связана ли кухня с рестораном.Если да, я хочу создать структуру JSON что-то вроде:

[  
   {  
      "Mexican":{  
         "venueNames":[  
            "Habanero",
            "Salsa"
         ]
      }
   },
   {  
      "Japanese":{  
         "venueNames":[  
            "Sushi Place",
            "catch"
         ]
      }
   }
]

Попытка построить JSON с использованием цикла for и .hasProperty, но не очень успешно.

Ответы [ 4 ]

0 голосов
/ 22 сентября 2018

Используя несколько функций es6, мы можем сгенерировать этот список с помощью Set , map и filter .

Сначала мы отобразимсписок кухонь и удалите недействительные, такие как undefined.При этом мы будем использовать Set для создания уникального списка кухонь.

Далее мы возьмем этот список и отобразим его снова, чтобы вернуть конечный объект, отфильтровывая исходный объект, где кухня соответствует текущему.итерация.Наконец, мы отображаем отфильтрованные результаты, чтобы вернуть только имя объекту venueNames.

Наш результат будет выглядеть следующим образом:

function getItems(places) {
  // Get a unique list of cuisines
  return [...new Set(places.map(p => p.cuisine).filter(c => c))]
    // Build the result
    .map(c => {
      return {
        [c]: {
          // Get a list of cuisines that match the current cuisine
          venueNames: places.filter(p => p.cuisine == c).map(c => c.name)
        }
      }
    })
}

const places = [
  {"name": "angelinas"},
  {"name": "besuto"},
  {"name": "catch","cuisine": "Japanese"},
  {"name": "center cut"},
  {"name": "fedora"},
  {"name": "Habanero","cuisine": "Mexican"},
  {"name": "Indies"},
  {"name": "new"},
  {"name": "RazINN"},
  {"name": "restaurantTestVenue779"},
  {"name": "restaurantTestVenue9703"},
  {"name": "Salsa ","cuisine": "Mexican"},
  {"name": "Sushi Place","cuisine": "Japanese"},
  {"name": "The Ashoka"},
  {"name": "The Poboys"},
  {"name": "the shogun"},
  {"name": "vinyard view"}
]

console.log(getItems(places))
0 голосов
/ 21 сентября 2018

Это простое сокращение массива.Если в ресторане есть определенная кухня, проверьте, определен ли уже результат для этой кухни.Если нет, создайте для него объект, в который вы можете нажать название ресторана.

const restaurants = [
   {  
    "name":"angelinas"
   },
   {  
    "name":"besuto"
   },
   {  
    "name":"catch",
    "cuisine":"Japanese"
   },
   {  
    "name":"center cut"
   },
   {  
    "name":"fedora"
   },
   {  
    "name":"Habanero",
    "cuisine":"Mexican"
   },
   {  
    "name":"Indies"
   },
   {  
    "name":"new"
   },
   {  
    "name":"RazINN"
   },
   {  
    "name":"restaurantTestVenue779"
   },
   {  
    "name":"restaurantTestVenue9703"
   },
   {  
    "name":"Salsa ",
    "cuisine":"Mexican"
   },
   {  
    "name":"Sushi Place",
    "cuisine":"Japanese"
   },
   {  
    "name":"The Ashoka"
   },
   {  
    "name":"The Poboys"
   },
   {  
    "name":"the shogun"
   },
   {  
    "name":"vinyard view"
   }
];
const cuisines = restaurants.reduce((result, restaurant ) => {
  if ( restaurant.hasOwnProperty( 'cuisine' )) {
    const { cuisine } = restaurant;
    if ( !result.hasOwnProperty( cuisine )) {
      result[ cuisine ] = {
        venueNames: []
      };
    }
    result[ cuisine ].venueNames.push( restaurant.name );
  }
  return result;
}, {});
console.log( cuisines );

По моему личному мнению, я бы использовал немного другую структуру.Если мы представляем коллекции с объектами, которые всегда одинаковы, мы можем упростить большинство преобразований.Это менее эффективно, чем делать все за один цикл, но код, используемый для создания преобразования, почти читабелен на английском языке:

const restaurants = [  
   { "name": "angelinas", "cuisine": null },
   { "name": "besuto", "cuisine": null },
   { "name": "catch", "cuisine": "japanese" },
   { "name": "center cut", "cuisine": null },
   { "name": "fedora", "cuisine": null },
   { "name": "habanero", "cuisine": "mexican" },
   { "name": "Indies", "cuisine": null },
   { "name": "new", "cuisine": null },
   { "name": "RazINN", "cuisine": null },
   { "name": "restaurantTestVenue779", "cuisine": null },
   { "name": "restaurantTestVenue9703", "cuisine": null },
   { "name": "Salsa ", "cuisine": "mexican" },
   { "name": "Sushi Place", "cuisine": "japanese" },
   { "name": "The Ashoka", "cuisine": null },
   { "name": "The Poboys", "cuisine": null },
   { "name": "the shogun", "cuisine": null },
   { "name": "vinyard view", "cuisine": null }
];
const create_cuisine = name => ({ name, "venues": [] });
const unique = () => {
  const seen = {};
  return item => {
    const json = JSON.stringify( item );
    return seen.hasOwnProperty( json )
      ? false
      : ( seen[ json ] = true );
  };
};
// Filter away all the restaurants without a cuisine value.
const restaurants_with_cuisine = restaurants.filter( restaurant => restaurant.cuisine );		
const cuisines = restaurants_with_cuisine
  // Extract the cuisine anmes from the restaurants.
  .map( restaurant => restaurant.cuisine )
  // Filter aways all the duplicates.
  .filter( unique() )
  // Create a new cuisine object.
  .map( cuisine_name => create_cuisine( cuisine_name ));
// Finally add all the restaurant names to the right cuisine.
restaurants_with_cuisine.forEach( restaurant => cuisines.find( cuisine => cuisine.name === restaurant.cuisine ).venues.push( restaurant.name ));

console.log( cuisines );
0 голосов
/ 21 сентября 2018

Вы можете использовать один цикл ниже.

data.forEach(function(item) {
    // if item has cuisine and cuisine not exist in new array
    if(item["cuisine"] != null && typeof newArr.find(v => v[item.cuisine] != null) == 'undefined') {
    // create new object with structure
    let obj = {};
    obj[item.cuisine] = {
         "venueNames":[item.name]
      };

    newArr.push(obj);
  }
  else {
    // else find existing cuisine and add new venue
    let obj = newArr.find(v => v.hasOwnProperty(item.cuisine));
    if(typeof obj != 'undefined') {
        obj[item.cuisine].venueNames.push(item.name);
    }
  }
});

JSFIDDLE

0 голосов
/ 21 сентября 2018

Вот что вы можете сделать!Сначала выполните итерацию по данным и используйте метод hasOwnProperty, чтобы проверить, существует ли кухня и существует ли она, затем проверьте, есть ли у вашего объекта кухни эта кухня и, если она есть, добавьте ее в нее.

const data = [{
        "name": "angelinas"
    },
    {
        "name": "besuto"
    },
    {
        "name": "catch",
        "cuisine": "Japanese"
    },
    {
        "name": "center cut"
    },
    {
        "name": "fedora"
    },
    {
        "name": "Habanero",
        "cuisine": "Mexican"
    },
    {
        "name": "Indies"
    },
    {
        "name": "new"
    },
    {
        "name": "RazINN"
    },
    {
        "name": "restaurantTestVenue779"
    },
    {
        "name": "restaurantTestVenue9703"
    },
    {
        "name": "Salsa ",
        "cuisine": "Mexican"
    },
    {
        "name": "Sushi Place",
        "cuisine": "Japanese"
    },
    {
        "name": "The Ashoka"
    },
    {
        "name": "The Poboys"
    },
    {
        "name": "the shogun"
    },
    {
        "name": "vinyard view"
    }
]

let cuisines = {};


for (const resturant of data) {
    if (resturant.hasOwnProperty('cuisine')) {

        if (cuisines.hasOwnProperty(resturant.cuisine)) {
            cuisines[resturant.cuisine].venueNames.push(resturant.name);
        } else {
            cuisines[resturant.cuisine] = {
                venueNames: [resturant.name]
            };
        }
    }
}
...