2

I am trying use Linq.js to get sub set of elements from JSON object in array.

I have array of JSON object that one of them looks like this

{
 "geometryType":2,
 "id":461219,
 "layer":"V_TRASA",
 "attributes":
 [
  {
   "type":"String","name":"DIMENZE","invariantStringValue":"80"
  },
  {
   "type":"String","name":"DRUH","invariantStringValue":"nezadáno"
  },
  {
   "type":"String","name":"ETAPA","invariantStringValue":"nezadáno"
  },
  {
   "type":"Long","name":"ID","invariantStringValue":"461219"
  },
  {
   "type":"String","name":"JMTLAK","invariantStringValue":"nezadáno"
  },
  {
   "type":"String","name":"MATERIAL","invariantStringValue":"litina"
  },
  {
   "type":"String","name":"RC","invariantStringValue":"Vodovodní řad, geod.zaměření"
  },
  {
   "type":"String","name":"ULOZENI","invariantStringValue":"zem"
  }
 ],
 "mbr":
 {
  "xmin":-496466.545,
  "ymin":-1155042.47,
  "xmax":-496466.11,
  "ymax":-1155042.145
 },
 "lineSymbology":
 {
  "IRgbColor":-16776961,
  "lineWeight":2
 },
 "points":
 [
  {"x":-496466.545,"y":-1155042.145},
  {"x":-496466.11,"y":-1155042.47}
 ]
}

each object has array property attributes. I am able select elements from array base on its property for example when I need elements that layer = V_TRASA and ID >460000 I will use this query

var queryResult2 = Enumerable.From(myArray)
        .Where("$.layer == 'V_TRASA' && $.id>460800" )           
        .Select("$")
        .ToArray(); 

But I need do some sub-query on attributes property that is array for example I need query when $.layer == 'V_TRASA' and element contains attribute name =='DIMENZE' and invariantStringValue == 80.

I am new in Linq so this is hard build this query form me.

Thanks for your help

Kutyel
  • 8,575
  • 3
  • 30
  • 61
Ivan Mjartan
  • 1,125
  • 1
  • 12
  • 23

1 Answers1

3

You can use Any function to determine whether a sequence contains any elements.

Here is an example:

var result = Enumerable.From(data)
        .Where(function(i) {
            var foundAttr = Enumerable.From(i.attributes).Any(
                function(j) { 
                    return j.name == 'DIMENZE'; 
            });
            return i.layer == 'V_TRASA' && i.id >460800 && foundAttr; 
        })
        .Select("$")
        .ToArray(); 

Edit

You can add prototypes to Enumerable, so you will be able to use them in linq expression:

Enumerable.prototype.ContainsName = function(attrName){
    console.log(attrName);
    return Enumerable.From(this).Any('i => i.name == "' + attrName + '"');
}

var result = Enumerable.From(data)
        .Where('i => i.layer == "V_TRASA" && i.id > 460800 && Enumerable.From(i.attributes).ContainsName("DIMENZE")')
        .Select("$")
        .ToArray();
Vano Maisuradze
  • 5,829
  • 6
  • 45
  • 73
  • Hi Vano! Thanks very much for your quick answer!!! It help me very much. And show me direction. But is there chance write this query without custom function? Something like this? I am trying built some query builder for may user. Something like: var queryResult2 = Enumerable.From(data) .Where("$.layer == 'V_TRASA' && Enumerable.From($.attributes).Contains($.name=='DIMENZE' && $.invariantStringValue=='80')" ) .Select("$") .ToArray(); – Ivan Mjartan May 07 '15 at 12:49
  • Do you mean extending linq.js by adding Contains function? – Vano Maisuradze May 07 '15 at 12:57
  • Hi Vano no I mean rewrite you code to string lambda selector. In one Where clause without custom function ... if it is possible. To explain my problem I have C# app where user has custom querybuilder and user is able write fragment of SQL code than I build inmemory sqlite Db and run this SQL. In javascript there is not possible this. So I am looking for something but I am not sure that custom function is Ok. Is there way rewrite it into one where clause without custom function? – Ivan Mjartan May 07 '15 at 13:13
  • something like this but this code is wrong .Where("$.layer == 'V_TRASA' && Enumerable.From($.attributes).Contains($.name=='DIMENZE' && $.invariantStringValue=='80')" ) – Ivan Mjartan May 07 '15 at 13:17
  • `Contains()` is already a method on an `Enumerable`... redefining it to do something else is a bad idea. – Jeff Mercado May 07 '15 at 16:46
  • @JeffMercado You are right. I changed to *ContainsName* – Vano Maisuradze May 07 '15 at 18:02