JsonIncludeService.cs
Home
/
Learn_CSS /
Learn_CSS.Model /
BLL /
JsonIncludeService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Newtonsoft.Json.Linq;
using Learn_CSS.Model.Extensions;
namespace Learn_CSS.Model.BLL
{
public class JsonIncludeService
{
/// <summary>
/// Содержит ли main в себе subobject
/// </summary>
/// <param name="main"></param>
/// <param name="subobject"></param>
/// <returns></returns>
public bool Include(JToken main, JToken subobject)
{
return RecursivInclude(main, subobject);
}
protected bool RecursivInclude(JToken main, JToken sub)
{
//Если у элементов разные типы то
if (main.Type != sub.Type)
return false;
if (main.Type == JTokenType.Property)
throw new Exception("Error type");
if (main is JValue)
{
return Include_Values((JValue)main, (JValue)sub, RecursivInclude);
}
if (main is JObject)
{
return Include_Object((JObject)main, (JObject)sub, RecursivInclude);
}
if (main is JArray)
{
return Include_Array_IgnorePosition((JArray)main, (JArray)sub, RecursivInclude);
}
throw new Exception("Unknow type");
}
#region Include
/// <summary>
/// Сравнивает элементы значимого типа
/// </summary>
protected bool Include_Values(JValue main, JValue sub, Func<JToken, JToken, bool> IncludeFunction)
{
return main.Value<string>() == sub.Value<string>();
}
/// <summary>
/// Сравнивает объекты по ключам
/// </summary>
protected bool Include_Object(JObject main, JObject sub, Func<JToken, JToken, bool> IncludeFunction)
{
//Получить все ключи
var main_childrens_properties = main.Properties().ToList();
var sub_childrens_properties = sub.Properties().ToList();
if (sub_childrens_properties.Count > main_childrens_properties.Count)
{
return false;
}
foreach (var sub_elem in sub_childrens_properties)
{
var main_elem = main_childrens_properties
.FirstOrDefault(e => e.Name == sub_elem.Name);
//В основном объекте нет ключа
if (main_elem == null)
{
return false;
}
if (!IncludeFunction(main_elem.First(), sub_elem.First()))
{
return false;
}
}
return true;
}
/// <summary>
/// Сравнение вхождения по массиву, со строгим учетом позиции main[i] = sub[i]
/// </summary>
protected bool Include_Array_WithPosition(JArray main, JArray sub, Func<JToken, JToken, bool> IncludeFunction)
{
var main_children = main.Children().ToList();
var sub_children = sub.Children().ToList();
if (sub_children.Count > main_children.Count)
{
return false;
}
for (int i = 0; i < sub_children.Count(); i++)
{
if (!IncludeFunction(main_children[i], sub_children[i]))
{
return false;
}
}
return true;
}
/// <summary>
/// Сравнение вхождение по массиву, без строго учета позиции main.contains(sub[i])
/// </summary>
protected bool Include_Array_IgnorePosition(JArray main, JArray sub, Func<JToken, JToken, bool> IncludeFunction)
{
var main_children = main.Children().ToList();
var sub_children = sub.Children().ToList();
if (sub_children.Count > main_children.Count)
{
return false;
}
while (sub_children.Count() > 0)
{
var find_main = main_children.FirstOrDefaultWithPosition(e => IncludeFunction(e, sub_children[0]));
if (find_main == null)
{
return false;
}
sub_children.RemoveAt(0);
main_children.RemoveAt(find_main.Index);
}
return true;
}
#endregion
}
}