2010-08-04 2 views
7

JSON 데이터의 저장 요구 사항을 알려진 기본 세트에 대해 deltifying하여 줄이려고합니다. 기본적으로, 내가 원하는 jQuery의 .extend() 기능을하는 역은 다음과 같은 테스트가 임의의 JSON 호환 개체를 전달하는 등입니다 :jQuery.extend의 ​​반전 (사실, ...)

function test_delta(defaults, delta) { 
    var current = $.extend(true, {}, defaults, delta); 

    QUnit.same(get_delta(current, defaults), delta); 
} 

내가 쓰기 시작하기 전에 내 자신의 get_delta(), 기존의 구현을 알고 누구입니까?

+0

하드 (중첩 된 루프) 방식으로 직접 처리해야합니다. 너도 알다시피. JSON 데이터에 임의의 깊이가있는 경우 훨씬 더 재미 있습니다. –

+0

그래, 나는 흥미로운 몇 가지 경우를 이미 생각해 냈다. 그래서 내가 "SO ORACLE"에 직접 물어보기 전에 물어볼 거라고 생각 했어. 아, 그럼. :-) –

+0

[jQuery source] (http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js)의 jQuery.fn.extend 함수를 살펴 보는 것이 좋습니다. – calvinf

답변

1

정말 찾고있는 것은 객체 차별화 된 알고리즘입니다.



function diff (obj1, obj2) { 
    var delta = {}; 

    for (var x in obj1) { 
     if (obj2.hasOwnProperty(x)) { 
      if (typeof obj2[x] == "object") { 
       //recurse nested objects/arrays 
       delta[x] = diff(obj1[x], obj2[x]); 
      } 
      else { 
       //if obj2 doesn't match then - modified attribute 
       if (obj2[x] != obj1[x]) { 
        delta[x] = obj1[x]; 
       } 
      }   
     } 
     else { 
      //obj2 doesn't have this - new attribute 
      delta[x] = obj1[x]; 
     } 
    } 

    return delta; 
} 

alert( 
    JSON.stringify(
    diff({ hello : 'world', gone : 'fishing' }, 
      { hello : 'world' }) 
) 
); 

//outputs: 
{ gone : 'fishing' } 

이 매우 기본적인 구현입니다 볼 수 있듯이 - - 별개의 객체가 obj2에 추가를 반환하여 완벽한 차동를 제공하기 위해이를 확장 할 수 쓸

너무 어려운 일이 아니다.

이 코드는 버그가 없으며 객체 프로토 타입과 함수는 다른 브라우저에서 다르게 처리되지만 데이터 구조의 데모로 충분합니다. 그런

+0

나는 내 자신을 구현하는 데 찌르다했지만, (단순히 배열과 삭제 된 속성을 가진) 명확하지 않은 가장자리 경우가있어서 데이터베이스 컬럼을 단순히 확장하기로 결정했다. –

1

시도 뭔가 :

jQuery.extend({ 
    deltaExtend: function(deep, target, defaults, delta){ 
     var result = jQuery.extend.apply(jQuery, arguments); 
     jQuery(result).data('delta', delta); 
     jQuery(result).data('defaults', defaults); 
     return result; 
    } 
}); 

사용 : 또한 N 개체에 대한 작업을 얻기 위해 불통 될 수

var result = $.deltaExtend(true, {}, defaults, delta); 
$(result).data('delta') //returns delta object 
$(result).data('defaults') //returns default object 

, 그냥 조금 더 생각을해야합니다.

+0

이것은 매우 흥미로운 아이디어입니다! 불행히도'$ .extend'는 "result"객체를 만드는 데 사용되지 않습니다. 이는 각 포틀릿이 자체 기본 설정을 정의 할 수있는 포털 시스템 용이었습니다. "현재"설정은 페이지 수명 기간 동안 자유롭게 수정되며 포틀릿의 상태를 서버로 다시 저장하기 위해 왔을 때 저장소 요구 사항을 줄이기 위해 "숨은"델타를 수행하기를 원했습니다. –

+0

다른 솔루션을 염두에두고, 어떤 브라우저를 지원하고 있으며 어떤 버전이 더 구체적으로 IE

1

주제 시작과 관련하여 다소 늦었지만 Underscore.js의 _.omit(object, *keys) 함수를 살펴볼 수 있습니다. 그것은 단지 그것을합니다.

+0

하지만 '열쇠'는 어떻게 압니까? – Bergi

+0

키는 기본값이 저장되어있는 개체에서옵니다. '_.keys (defaultObject)'는 키 배열을 제공합니다. – oley

+0

당신은 대답에 언급 했어야 만합니다 ... 그리고이 방법은 모든 * 변경된 * 속성이 아닌 * 추가 ​​된 속성에 대해서만 작동합니다. – Bergi