【问题标题】:How to link nested json relationship values objects with lodash?如何将嵌套的 json 关系值对象与 lodash 链接?
【发布时间】:2018-01-14 04:21:04
【问题描述】:

我正在尝试为嵌套的 json 对象分配/合并(真的不知道哪个 lodash 函数)。

我有以下 json 结构:

{
"sports": [{
        "id": "c60d0c48-151e-4fa2-bdf8-48cdfa77ad1d",
        "name": "Soccer",
        "slug": "soccer"
    }],
"competitions": [{
        "id": "4c19ca7c-4d17-46ce-bb4e-e25a4ebe5dbe",
        "name": "English Premier League",
        "sportId": "c60d0c48-151e-4fa2-bdf8-48cdfa77ad1d"
    }],
"contests": [{
        "id": "09cee598-7736-4941-b5f5-b26c9da113fc",
        "name": "Super Domingo Ingles",
        "status": "live",
        "competitionId": "4c19ca7c-4d17-46ce-bb4e-e25a4ebe5dbe"
    }]
}

我想得到一个contest 对象,它们的关系链接嵌套。预期的对象是这样的:

{
        "id": "09cee598-7736-4941-b5f5-b26c9da113fc",
        "name": "Super Domingo Ingles",
        "status": "live",
        "competition": {
           "id": "4c19ca7c-4d17-46ce-bb4e-e25a4ebe5dbe",
           "name": "English Premier League",
           "sport": {
             "id": "c60d0c48-151e-4fa2-bdf8-48cdfa77ad1d",
              "name": "Soccer",
              "slug": "soccer"
            }
        }
    }]
}

如何使用 lodash 完成这种关系?它也可以使用纯javascript。

【问题讨论】:

  • 你尝试了什么,问题是什么?

标签: javascript json lodash


【解决方案1】:

没有可用于扁平化关系 JSON 结构的内置 lodash 函数。但这样的事情应该适合你:

    const sourceJSON = {
    "sports": [{
            "id": "c60d0c48-151e-4fa2-bdf8-48cdfa77ad1d",
            "name": "Soccer",
            "slug": "soccer"
        }],
    "competitions": [{
            "id": "4c19ca7c-4d17-46ce-bb4e-e25a4ebe5dbe",
            "name": "English Premier League",
            "sportId": "c60d0c48-151e-4fa2-bdf8-48cdfa77ad1d"
        }],
    "contests": [{
            "id": "09cee598-7736-4941-b5f5-b26c9da113fc",
            "name": "Super Domingo Ingles",
            "status": "live",
            "competitionId": "4c19ca7c-4d17-46ce-bb4e-e25a4ebe5dbe"
        }]
    }

    function findSport(source, sportId) {
    	let sport = _.find(source['sports'], {id: sportId});
    	if(!sport) {
    		return {};
    	}
    
    	return {
    		id: sport.id,
    		name: sport.name,
    		slug: sport.slug,
    	}	
    }
    
    function findCompetition(source, competitionId) {
    	let competition = _.find(source['competitions'], {id: competitionId});
    	if(!competition) {
    		return {};
    	}
    
    	return {
    		id: competition.id,
    		name: competition.name,
    		sport: findSport(source, competition.sportId),
    	}
    }
    
    function flattenContests(source) {
    	return _.map(source['contests'], (contest) => {
    		return {
    			id: contest.id,
    			name: contest.name,
    			status: contest.status,
    			competition: findCompetition(source, contest.competitionId),
    		}
    	});	
    }
    
    console.log(flattenContests(sourceJSON));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

请注意,考虑到您的原始 JSON,展平对象应该是 contests 的数组(因为 contests 本身就是一个数组),而不是您期望的单个比赛对象。

【讨论】:

    【解决方案2】:

    您确实需要向我们展示您的尝试,以便我们可以就您面临的问题向您提供建议,否则您只是要求提供代码编写服务 ($)。

    但是,在 ES2016 中,您可以这样做。

    'use strict';
    
    const obj = {
      sports: [{
        id: 'c60d0c48-151e-4fa2-bdf8-48cdfa77ad1d',
        name: 'Soccer',
        slug: 'soccer',
      }],
      competitions: [{
        id: '4c19ca7c-4d17-46ce-bb4e-e25a4ebe5dbe',
        name: 'English Premier League',
        sportId: 'c60d0c48-151e-4fa2-bdf8-48cdfa77ad1d',
      }],
      contests: [{
        id: '09cee598-7736-4941-b5f5-b26c9da113fc',
        name: 'Super Domingo Ingles',
        status: 'live',
        competitionId: '4c19ca7c-4d17-46ce-bb4e-e25a4ebe5dbe',
      }],
    };
    
    const transformed = obj.contests.map((contest) => {
      const competition = obj.competitions.find(item => item.id === contest.competitionId);
      const sport = obj.sports.find(item => item.id === competition.sportId);
      const sportLevel = { ...sport };
      const competitionLevel = { ...competition, sport: sportLevel };
      delete competitionLevel.sportId;
      const contestLevel = { ...contest, competition: competitionLevel };
      delete contestLevel.competitionId;
      return contestLevel;
    });
    
    console.log(JSON.stringify(transformed, null, 2));

    【讨论】:

      【解决方案3】:

      您不需要任何特殊的赋值运算符或 lodash。您只需使用=

      ogObject = {
      "sports": [{
              "id": "c60d0c48-151e-4fa2-bdf8-48cdfa77ad1d",
              "name": "Soccer",
              "slug": "soccer"
          }],
      "competitions": [{
              "id": "4c19ca7c-4d17-46ce-bb4e-e25a4ebe5dbe",
              "name": "English Premier League",
              "sportId": "c60d0c48-151e-4fa2-bdf8-48cdfa77ad1d"
          }],
      "contests": [{
              "id": "09cee598-7736-4941-b5f5-b26c9da113fc",
              "name": "Super Domingo Ingles",
              "status": "live",
              "competitionId": "4c19ca7c-4d17-46ce-bb4e-e25a4ebe5dbe"
          }]
      };
      newObject = ogObject.contests[0];
      for(var i = 0; i<ogObject.competitions.length;i++){
          if(ogObject.competitions[i].id == newObject.competitionId){
              newObject.competition = ogObject.competitions[i];
              for(var j = 0; j<ogObject.sports.length;j++){
                  if(ogObject.sports[j].id == newObject.competition.sportId){
                      newObject.competition.sport = ogObject.sports[j];
                      break;
                  }
              }
              break;
          }
      }
      console.log(newObject)

      这可能是 lodash 的内置函数,但我对此表示怀疑。它需要预先定义您的架构知识,以及 SportId 和运动、competitionId 和比赛等之间的关系......

      【讨论】:

        猜你喜欢
        • 2021-07-15
        • 2019-05-11
        • 1970-01-01
        • 2016-02-02
        • 2016-09-16
        • 2020-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多