2013-01-02 13 views
6

Ho due JToken che rappresentano gli array JSON di oggetti e vorrei unirli. JToken ha un metodo Concat ma produce null come risultato quando provo ad usarlo.Unire due matrici Json.NET concatenando gli elementi contenuti

Action<JToken> Ok = (x) => 
{ 
    Debug.WriteLine(x); 
    /* outputs 
    [ 
     { 
     "id": 1, 
     }, 
     { 
     "id": 2, 
     } 
    ] 
    */ 

    x = (x).Concat<JToken>(x) as JToken; 
    Debug.WriteLine(x); // null 
}; 

Come posso farlo funzionare?

+0

Potete per favore mostrare come si utilizza il metodo 'Concat' fornendo i dati di esempio codice di +? – GameScripting

+0

@GameScripting bene il codice è proprio qui in questione, in particolare la riga 'x = (x) .Concat (x) come JToken'. UPD: puoi vedere il blocco di codice che ho fornito? – Anton

+0

Oh mi dispiace, hai assolutamente ragione. – GameScripting

risposta

5
JToken.FromObject(x.Concat(x)) 
1

avevo bisogno stesso, questo è quello che mi è venuta

https://github.com/MrAntix/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Linq/MergeExtensions.cs

public static void MergeInto(
    this JContainer left, JToken right, MergeOptions options) 
{ 
    foreach (var rightChild in right.Children<JProperty>()) 
    { 
     var rightChildProperty = rightChild; 
     var leftPropertyValue = left.SelectToken(rightChildProperty.Name); 

     if (leftPropertyValue == null) 
     { 
      // no matching property, just add 
      left.Add(rightChild); 
     } 
     else 
     { 
      var leftProperty = (JProperty) leftPropertyValue.Parent; 

      var leftArray = leftPropertyValue as JArray; 
      var rightArray = rightChildProperty.Value as JArray; 
      if (leftArray != null && rightArray != null) 
      { 
       switch (options.ArrayHandling) 
       { 
        case MergeOptionArrayHandling.Concat: 

         foreach (var rightValue in rightArray) 
         { 
          leftArray.Add(rightValue); 
         } 

         break; 
        case MergeOptionArrayHandling.Overwrite: 

         leftProperty.Value = rightChildProperty.Value; 
         break; 
       } 
      } 

      else 
      { 
       var leftObject = leftPropertyValue as JObject; 
       if (leftObject == null) 
       { 
        // replace value 
        leftProperty.Value = rightChildProperty.Value; 
       } 

       else 
        // recurse object 
        MergeInto(leftObject, rightChildProperty.Value, options); 
      } 
     } 
    } 
} 
+0

'left.SelectToken (rightChildProperty.Name);' dovrebbe essere 'left [rightChildProperty.Name];' ... almeno nel mio caso (4.0 R8) –

20

Usa JContainer.Merge() con MergeArrayHandling.Concat.

Questo è disponibile a partire da Json.NET 6 Release 4. Quindi, se i tuoi array sono in un JContainer (ad esempio un JObject), questa è una soluzione semplice e affidabile.

Esempio:

JObject o1 = JObject.Parse(@"{ 
    'FirstName': 'John', 
    'LastName': 'Smith', 
    'Enabled': false, 
    'Roles': [ 'User' ] 
}"); 
JObject o2 = JObject.Parse(@"{ 
    'Enabled': true, 
    'Roles': [ 'Operator', 'Admin' ] 
}"); 

o1.Merge(o2, new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Concat }); 

string json = o1.ToString(); 
// { 
// "FirstName": "John", 
// "LastName": "Smith", 
// "Enabled": true, 
// "Roles": [ 
//  "User", 
//  "Operator", 
//  "Admin" 
// ] 
// } 
Problemi correlati