diff --git a/src/json-ld.net/Core/JsonLdApi.cs b/src/json-ld.net/Core/JsonLdApi.cs
index 60d61b8..186d913 100644
--- a/src/json-ld.net/Core/JsonLdApi.cs
+++ b/src/json-ld.net/Core/JsonLdApi.cs
@@ -1072,14 +1072,34 @@ internal virtual void GenerateNodeMap(JToken element, JObject
///
internal virtual void GenerateNodeMap(JToken element, JObject
nodeMap, string activeGraph, JToken activeSubject, string activeProperty, JObject list)
+ {
+ GenerateNodeMap(element, nodeMap, activeGraph, activeSubject, activeProperty, list, skipSetContainsCheck: false);
+ }
+
+ private void GenerateNodeMap(JToken element, JObject nodeMap,
+ string activeGraph, JToken activeSubject, string activeProperty, JObject list, bool skipSetContainsCheck)
{
// 1)
if (element is JArray)
{
+ JsonLdSet set = null;
+
+ if (list == null)
+ {
+ set = new JsonLdSet();
+ }
+
// 1.1)
foreach (JToken item in (JArray)element)
{
- GenerateNodeMap(item, nodeMap, activeGraph, activeSubject, activeProperty, list);
+ skipSetContainsCheck = false;
+
+ if (set != null)
+ {
+ skipSetContainsCheck = set.Add(item);
+ }
+
+ GenerateNodeMap(item, nodeMap, activeGraph, activeSubject, activeProperty, list, skipSetContainsCheck);
}
return;
}
@@ -1204,7 +1224,7 @@ internal virtual void GenerateNodeMap(JToken element, JObject
if (list == null)
{
// 6.6.2.1+2)
- JsonLdUtils.MergeValue(node, activeProperty, reference);
+ JsonLdUtils.MergeValue(node, activeProperty, reference, skipSetContainsCheck);
}
else
{
diff --git a/src/json-ld.net/Core/JsonLdSet.cs b/src/json-ld.net/Core/JsonLdSet.cs
new file mode 100644
index 0000000..a43edc0
--- /dev/null
+++ b/src/json-ld.net/Core/JsonLdSet.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
+
+namespace JsonLD.Core
+{
+ internal sealed class JsonLdSet
+ {
+ private readonly Lazy> _objects;
+
+ internal JsonLdSet()
+ {
+ _objects = new Lazy>(() => new HashSet(StringComparer.Ordinal));
+ }
+
+ internal bool Add(JToken token)
+ {
+ if (token == null)
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ if (token is JObject)
+ {
+ var id = token["@id"];
+
+ return id != null && _objects.Value.Add(id.Value());
+ }
+
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/json-ld.net/Core/JsonLdUtils.cs b/src/json-ld.net/Core/JsonLdUtils.cs
index b0d61b8..fc07804 100644
--- a/src/json-ld.net/Core/JsonLdUtils.cs
+++ b/src/json-ld.net/Core/JsonLdUtils.cs
@@ -148,8 +148,12 @@ public static bool DeepContains(JArray values, JToken value)
return false;
}
- internal static void MergeValue(JObject obj, string key, JToken
- value)
+ internal static void MergeValue(JObject obj, string key, JToken value)
+ {
+ MergeValue(obj, key, value, skipSetContainsCheck: false);
+ }
+
+ internal static void MergeValue(JObject obj, string key, JToken value, bool skipSetContainsCheck)
{
if (obj == null)
{
@@ -161,8 +165,10 @@ internal static void MergeValue(JObject obj, string key, JToken
values = new JArray();
obj[key] = values;
}
- if ("@list".Equals(key) || (value is JObject && ((IDictionary
- )value).ContainsKey("@list")) || !DeepContains(values, (JToken)value))
+ if (skipSetContainsCheck ||
+ "@list".Equals(key) ||
+ (value is JObject && ((IDictionary)value).ContainsKey("@list")) ||
+ !DeepContains(values, (JToken)value))
{
values.Add(value);
}