如果键存在,则使用键和值形成JSON

时间:2018-09-21 13:05:44

标签: javascript arrays json javascript-objects

我有一个类似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"
         ]
      }
   }
]

曾尝试使用for循环和.hasProperty构建JSON,但未成功。

4 个答案:

答案 0 :(得分:1)

这是您可以做的! 首先遍历数据,然后使用方法“ 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]
            };
        }
    }
}

答案 1 :(得分:0)

这是对数组的简单简化。如果餐厅有已定义的美食,请检查结果是否已定义了该美食。如果没有,请为其创建一个对象,在其中您可以将餐厅名称推送至此。

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 );

答案 2 :(得分:0)

您可以在下面的一个循环中使用。

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

答案 3 :(得分:0)

使用一些es6功能,我们可以使用Setmapfilter生成此列表。

我们将首先映射一列美食,然后删除无效的美食,例如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))