How to search in subarrays?

Mar 15, 2013 at 1:14 PM
Edited Mar 15, 2013 at 1:15 PM
I have an array:

var data = [
{
"reqSN" : 96,
"reqId" : "96",
"reqName" : "UFT12630",
"reqItemList" : null
},
{
"reqSN" : 102,
"reqId" : "102",
"reqName" : "UFT1263011",
"reqItemList" : [
  {
    "reqSN" : 102,
    "reqItemSN" : 24350,
    "reqPos" : 4545
  },
  {
    "reqSN" : 102,
    "reqItemSN" : 24256,
    "reqPos" : 4545
  },
  {
    "reqSN" : 102,
    "reqItemSN" : 24255,
    "reqPos" : 4545
  }
]
},
{
"reqSN" : 104,
"reqId" : "104",
"reqName" : "3M - 3461-0002 - Card Edge Connector",
"reqItemList" : [
  {
    "reqSN" : 104,
    "reqItemSN" : 41,
    "reqPos" : 10
  },
  {
    "reqSN" : 104,
    "reqItemSN" : 24258,
    "reqPos" : 10
  }
]
},
{
"reqSN" : 105,
"reqId" : "105",
"reqName" : "Federleiste"
}
];


How to select the records that has the "reqItemSN" = 24256 ?
Coordinator
Mar 15, 2013 at 4:04 PM
Edited Mar 15, 2013 at 4:07 PM
Let's restate your question to "How do I select the records where the record's 'reqItemList' contains an item with a 'reqItemSN' equal to 24256?"

Now, the "How do I select the records where" part of the question can be expressed as:
$linq(data).where( ... )
The remainder of the question, "where the record's 'reqItemList' contains an item with a 'reqItemSN' equal to 24256", can be further restated as "where any of the record's 'reqItemList' items have a 'reqItemSN' equal to 24256". This can be expressed as:
function (x) 
{
    return $linq(x.reqItemList).any(function (y) { return y.reqItemSN == 24256; }); 
}
Put these both together and you get the following:
$linq(data).where(function (x)
    {
        return $linq(x.reqItemList).any(function (y) { return y.reqItemSN == 24256; });
    })
    .toArray();
In the example data you presented, not all of the records have a value for 'reqItemList' (in one record it's set to null and in another it is not given). This code should still work correctly (since "$linq(null)" behaves the same as "$linq([])"), but if you wanted to optimize the code, you could use something like the following:
$linq(data).where(function (x)
    {
        if (x.reqItemList == null)
            return false;
        
        return $linq(x.reqItemList).any(function (y) { return y.reqItemSN == 24256; });
    })
    .toArray();
Mar 15, 2013 at 4:10 PM
Thank you very much for such fast response battousai999!

I tried many JSON search libraries, but this one is the best, yet I have not too much experience with it.
I would like to ask one more question. I would like to replace one reqItem record in the "reqItemList" array searched by "reqItemSN" : 41, with another record. Is there any better way to do this using $linq or I have to do it with plain javascript 'splice' functions?

Thank you a lot for your help!
Coordinator
Mar 15, 2013 at 4:40 PM
Edited Mar 15, 2013 at 5:02 PM
Since creating a $linq object only does a shallow copy of the array (i.e., a copy of the array, but containing the same objects within the copy as the original), you should be able to search the array using $linq and modify the objects within the results (which will modify the objects within the original array).

So, you might use the following:
var results = $linq(data).where(function (x)
    {
        if (x.reqItemList == null)
            return null;
            
        return $linq(x.reqItemList).any(function (y) { return y.reqItemSN == 41; });
    });
    
// Using 'foreach' in case there are multiple items returned by the search
results.foreach(function (x)
    {
        // Projecting a new array (with the desired replacement) from 
        // the old array value
        x.reqItemList = $linq(x.reqItemList)
            .select(function (item)
                {
                    if (item.reqItemSN == 41)
                    {
                        // return the new item here...
                    }
                    else
                        return item;
                })
            .toArray();
    });
Mar 18, 2013 at 9:07 AM
Thank you a lot battousai999 :)