아 리 전단 2018 가을 수필 시험 문제: JSON 대상자 에 게 고리 가 있 는 지 판단

5236 단어 web자바 script
며칠 전에 아 리 전단 가을 붓 시험 문 제 를 풀 었 는데 충격 이 심해 서 일자 리 를 찾기 가 어 려 웠 습 니 다.근 데 시험 끝나 면 다시 봐 야 돼.JSON 대상 에 고리 가 있 는 지 아 닌 지 를 판단 하 는 문제 가 있 었 던 것 으로 기억한다.JSON 대상 을 포맷 하 는 JSON.stringify() 방법 을 사용 할 때 이 대상 에 순환 도로 가 있 으 면 이상 을 던 지기 때문이다. Uncaught TypeError: Converting circular structure to JSON예 를 들 어 코드:
var obj={
  f:{
    name:'fff',
    age:20,
    call:null
  }
}
obj.f.call=obj.f;
//Uncaught TypeError: Converting circular structure to JSON(…)
JSON.stringify(obj)

당시 시험 을 볼 때 오랫동안 생각 했 지만 코드 를 쓰 지 못 해 아이디어 가 있 었 지만 코드 를 쓰기 가 어 려 울 것 같 았 다.그래서 요 며칠 동안 넉넉 한 시간 을 틈 타 코드 작성 을 마 쳤 습 니 다.
function isCycle(obj){
  var arr=['obj'],l=1,k=0,flag=false,str='';
  while(l>k){
    var obj_tmp=eval(arr[k]);
    var all=Object.keys(obj_tmp);
    str=arr[k]+'.';
    if(all.length>0){
      for(var i=0,length=all.length;iif((typeof obj_tmp[all[i]]) !='object'||Object.prototype.toString.call(obj_tmp)=='[object String]')continue;
        for(var j=0;jif(obj_tmp[all[i]]==eval(arr[j])){
            flag=true;
            break;
          }
        }
        if(flag)break;
        arr.push(str+all[i]);
        l++;
      }
    }
    if(flag)break;
    k++;
  }
  if(flag)return true;
  else return false;
}

최종 테스트 는 다음 과 같다.
var obj={
  f:{
    name:'fff',
    age:20,
    call:null
  }
};
obj.f.call='fff';

console.log(isCycle(obj));//output:false;

obj.f.call=obj.f;

console.log(isCycle(obj));//output:true;

obj.f.call=new Date();

console.log(isCycle(obj));//output:false;

obj.f.call=new String('ddd');

console.log(isCycle(obj));//output:false;
obj.f.call=[obj.f];

console.log(isCycle(obj));//output:true;

전체적인 사상 은 BFS 입 니 다. 대상 의 모든 속성 을 우선 검색 하고 한 배열 이 옮 겨 다 니 는 모든 값 을 대상 으로 하 는 속성 을 유지 하 는 것 입 니 다. 새로운 속성 을 옮 겨 다 닐 때 먼저 속성 배열 의 특정한 항목 과 같 는 지 확인 합 니 다. 같 으 면 하나의 고리 임 을 증명 하고 true 로 돌아 가 야 합 니 다.그렇지 않 으 면 이 속성 을 속성 배열 에 넣 고 계속 옮 겨 다 닙 니 다.속성 이 모두 배열 에 존재 하기 때문에 사실 속성 을 옮 겨 다 니 는 것 은 전체 속성 배열 을 옮 겨 다 니 는 것 입 니 다. 순환 종료 조건 은 전체 배열 을 옮 겨 다 니 는 속성 입 니 다.이 방식 에 대해 몇 가지 주의해 야 할 것 이 있다.
  • 상기 사상 에서 관건 적 인 점 은 배열 이 속성 값 을 대상 으로 하 는 속성 만 저장 하 는 것 이다. 속성 값 이 기본 유형의 값 이기 때문에 반환 을 구성 할 수 없고 값 이 대상 인 속성 간 의 상호 참조 만 반환 을 구성 할 수 있 기 때문이다.일부 특수 한 대상, 예 를 들 어 기본 포장 유형, 날짜 유형 도 요구 에 부합 되 지 않 기 때문에 Object.keys(attr).length>0 필 터 를 통 해 제거 할 수 있 지만 String 대상 에 대해 진일보 한 필 터 를 해 야 한다. 왜냐하면 인용 이 되 지 않 고 위의 방식 도 필 터 를 하지 않 기 때문이다.그래서 Object.prototype.toString.call(obj_tmp)=='[object String]' 로 걸 러 내야 합 니 다.
  • 다른 하 나 는 두 속성 이 같은 지 여 부 를 어떻게 판단 하 는 지 주의해 야 한다. 이때 속성 배열 안의 모든 속성의 값 을 복원 해 야 한다.나 는 잠시 특별히 좋 은 방법 을 생각 하지 못 하고 효율 이 낮은 방법 을 썼 다.존 속성 은 포인트, 예 를 들 어 obj, obj.f, obj.f.call 를 사 용 했 기 때문에 복원 eval() 방법 을 사 용 했 기 때문에 코드 효율 이 좀 낮 을 수 있 지만 정상적으로 작 동 하 는 것 도 제 큰 유감 입 니 다!!

  • 좋 은 방법 이 있 으 시 면 토론 하 셔 도 됩 니 다.만약 잘못 이 있 으 면 아낌없이 지적 하여 바로잡아 주 십시오.

    좋은 웹페이지 즐겨찾기