Σε αυτό το μέρος του οδηγού θα δούμε όλες εκείνες τις εντολές που χρησιμοποιούνται για την προβολή και το φιλτράρισμα δεδομένων στην linq.js.

linqjs

Flatten

Η εντολή Flatten είναι μια εντολή μέσω της οποίας ένας πολυδιάστατος πίνακας μπορεί να μετατραπεί σε μονοδιάστατο. Η συγκεκριμένη εντολή λαμβάνει υπόψη μόνο μεμονωμένα στοιχεία μέσα στους εκάστοτε πίνακες και υπο-πίνακες. Στην λειτουργία του δεν συμπεριλαμβάνεται η μετατροπή αντικειμένων με τις ιδιότητες τους σε μονοδιάστατους πίνακες.

Αρχείο: flatten.js

var array = [1, [234,2,[62,3]],[324,5],3];
Enumerable.From(array).Flatten().ToArray();
var array = [1,[234,2,5,{obj_prop: 1 , obj_arr: [123,66]}],[324,5],3];
Enumerable.From(array).Flatten().ToArray();

Αποτέλεσμα:

image

Pairwise

Η εντολή Pairwise είναι μια εντολή συνδυασμού της κάθε προηγούμενης τιμής με την επόμενη σε ένα σύνολο δεδομένων που εισάγουμε σε αυτήν. Μπορούμε είτε να χρησιμοποιήσουμε κάποιο είδος εντολής σε μορφή αλφαριθμητικού (String) για να εκτελέσουμε απλές πράξεις μεταξύ των στοιχείων αυτών ή μπορούμε να τοποθετήσουμε δική μας function η οποία ως παραμέτρους εισαγωγής διαθέτει ένα «prev» και ένα «next» και αυτό που επιστρέφεται ως αποτέλεσμα από την function δίνεται ως νέα τιμή στο μετασχηματισμένο σύνολο. Επίσης μπορούμε με συνδυασμό εντολής From να κάνουμε την ίδια πράξη μέσα από πίνακα αντικειμένων.

Αρχείο: pairwise.js

var array1 = Enumerable.Range(1,10).Pairwise("prev,next=>prev + ':' + next").ToArray();
var array2 = Enumerable.Range(1,10).Pairwise(function(prev,next){ 
 return prev*next;
}).ToArray();
var array3 = [{prop1: 1, prop2: 2}, {prop1: 3 , prop2: 4}];
Enumerable.From(array3).Pairwise("prev,next => prev.prop1 + ':' + next.prop1").ToArray();

Αποτέλεσμα:

image

Scan

Το Scan είναι μια εντολή παρόμοια με το Pairwise μόνο που στην συγκεκριμένη περίπτωση πρώτα υπολογίζεται το αποτέλεσμα του πρώτου συνδυασμού (δηλαδή του πρώτου στοιχείου με το δεύτερο) και ύστερα μεταφέρεται αυτό το αποτέλεσμα ως η «προηγούμενη» τιμή για τον επόμενο συνδυασμό, λειτουργεί δηλαδή διαδοχικά σαν σαρωτής (scanner). Μπορεί να χρησιμοποιηθεί είτε αλφαριθμητική εντολή είτε function για τον ορισμό της λειτουργίας του, και επίσης μέσω της χρήσης εντολής From και σε πίνακα αντικειμένων.

Αρχείο: scan.js

Enumerable.Range(1,10).Scan("a,b=>a+':'+b").ToArray();
Enumerable.Range(1,10).Scan(function(prev,next){
    return prev*next;
}).ToArray();
var array3 = [{prop1: 1, prop2: 2}, {prop1: 3 , prop2: 4}];
Enumerable.From(array3).Scan("prev,next => prev.prop1 + ':' + next.prop1").ToArray();

Αποτέλεσμα:

image

Select

Η Select είναι μια εντολή όπου μπορούμε να μετασχηματίσουμε μεμονωμένα το κάθε στοιχείο ενός πίνακα δεδομένων (είτε πρόκειται για πίνακα αντικειμένων), επιστρέφοντας έναν νέο πίνακα με ίδιο πλήθος στοιχείων αλλά μετασχηματισμένο το κάθε στοιχείο στην αντίστοιχη θέση του. Αν είχαμε τα στοιχεία 1,2,3,4, και θέλαμε να επιστρέψουμε τους ζυγούς αριθμούς διπλάσιους αλλά τους μονούς τριπλάσιους, τότε το αναμενόμενο αποτέλεσμα θα πρέπει να ήταν 3, 4, 9, 8. Ας δούμε αυτό πως μπορεί να πραγματοποιηθεί μέσα από τον παρακάτω παράδειγμα.

Αρχείο: select.js

Enumerable.Range(1,4).Select("item => (item %2 == 0) ? item*2 : item*3;").ToArray();
Enumerable.Range(1,4).Select(function(item){
    if((item % 2) == 0){
        return item * 2;
    }else{
        return item * 3;
    }
}).ToArray();

Αποτέλεσμα:

image

Να σημειώσουμε εδώ ότι εκτός από την χρήση Range μπορούμε με την χρήση της εντολής From να μετασχηματίσουμε οποιοδήποτε άλλο πίνακα είτε διαθέτει αντικείμενα είτε άλλους πίνακες κ.τ.λ. Σε περίπτωση που έχουμε να κάνουμε με μετασχηματισμό πίνακα αντικειμένων μπορούμε να διαλέξουμε κάποια συγκεκριμένη ιδιότητα κάποιου αντικειμένου ως επιστροφή για τον μετασχηματισμό αλλάζοντας πλήρως την επιστροφή του αποτελέσματος. Αυτό σημαίνει πως αν για είσοδο είχαμε για παράδειγμα αντικείμενα με ιδιότητες name και age, θα μπορούσαμε να επιλέξουμε να επιστραφεί μόνο το age ως απλός αριθμός και όχι ως αντικείμενο μετασχηματίζοντας τον πίνακα έτσι από έναν πίνακα αντικειμένων σε έναν πίνακα αριθμών με σημασιολογία ηλικιών.

Αρχείο: select-object.js

var array3 = [{prop1: 1, prop2: 2}, {prop1: 3 , prop2: 4}];
Enumerable.From(array3).Select("item=> item.prop1").ToArray();

Αποτέλεσμα:

image

SelectMany

Η εντολή SelectMany είναι μια εντολή παρόμοια με την Select μόνο που στην επιστροφή αποτελέσματος αν αυτό που θα επιστραφεί είναι ένας πίνακας από στοιχεία τότε θα συγχωνευθεί σε ένα ενιαίο πίνακα. Αυτή η λειτουργία λαμβάνεται υπόψη μόνο για το πρώτο επίπεδο πινάκων που μπορεί να επιστραφούν από ένα αποτέλεσμα. Επίσης μπορεί να χρησιμοποιηθεί ως αποτέλεσμα επιστροφής και αντικειμένων μορφής Enumerable της linq.js.

Στο παρακάτω παράδειγμα για ένα εύρος αριθμητικών δεδομένων από το 1 έως το 5 θα επιστρέψουμε αυτές τις τιμές , κάθε μία δυο φορές διαδοχικά, επομένως θα πρέπει να περιμένουμε το εξής αποτέλεσμα [1,1,2,2,3,3,4,4,5,5].

Αρχείο: select-many.js

Enumerable.Range(1,5).SelectMany("[$,$]").ToArray();
Enumerable.Range(1,5).SelectMany(function(item){
    return [item,item];
}).ToArray();
Enumerable.Range(1,5).SelectMany(function(item){
    return Enumerable.From([item,item]);
}).ToArray();

Αποτέλεσμα:

image

Εκτός από την τιμή του κάθε στοιχείου στην εκτέλεση της SelectMany μας δίνεται επίσης και το index (ο δείκτης του στοιχείου) της κάθε περίπτωσης, το οποίο μπορούμε να χρησιμοποιήσουμε εμείς όπως θέλουμε. Στο παρακάτω παράδειγμα επιστρέφουμε τους αριθμούς εισόδου σε πλήθος αυξανόμενο κατά την θέση εμφάνιση τους.

Αρχείο: select-many-index.js

Enumerable.Range(5,5).SelectMany("value,index=>Enumerable.Repeat(value,index+1)").ToArray();
Enumerable.Range(5,5).SelectMany(function(value,index){
    var result = [];
    for(var i=0; i < index+1;i++){
        result.push(value);
    }
    return result;
}).ToArray();

Αποτέλεσμα:

image

OfType

Η εντολή OfType είναι μια εντολή επιλογής στοιχείων με συγκεκριμένο τύπο δεδομένων μέσα από ένα σύνολο. Αυτό σημαίνει πως αν έχουμε έναν πίνακα από διαφορετικού είδους στοιχεία όπως για παράδειγμα αριθμούς και αλφαριθμητικά και booleans, τότε μπορούμε να επιστρέψουμε από αυτό το σύνολο μόνο τους αριθμούς ή μόνο τα αλφαριθμητικά ως νέο ξεχωριστό πίνακα.

Αρχείο: ofType.js

Enumerable.From([1,"a",2,"b","c",3,true,false]).OfType(Number).ToArray();
Enumerable.From([1,"a",2,"b","c",3,true,false]).OfType(String).ToArray();
Enumerable.From([1,"a",2,"b","c",3,true,false]).OfType(Boolean).ToArray();

Αποτέλεσμα:

image

Μπορούμε εκτός από τους προεπιλεγμένους τύπους μεταβλητών να κάνουμε επιλογή και των δικών μας τύπων αντικειμένων μέσω της εντολής αυτής, το παρακάτω παράδειγμα, ξεκαθαρίζει τον τρόπο χρήσης του για δικούς μας τύπους:

Αρχείο: object-ofType.js

function Person(fname,lname){
 this.firstName = fname;
 this.lastName = lname;
}

Enumerable.From([
 new Person("Konstantinos","Koletsos"),1,3,4,"test",
 new Person("Pantelis","Papasavvas")]).OfType(Person).Select("$.firstName +' '+ $.lastName").ToArray();

Αποτέλεσμα:

image

Zip

Η εντολή Zip είναι μια εντολή συνδυασμού δύο συνόλων δεδομένων σε ένα ενιαίο σύνολο. Έτσι αν θέλουμε να συνδυάσουμε τον πίνακα Α: [1,2,3,4,5] με τον πίνακα Β: [6,7,8,9,10], τότε θα μας επιστρέφεται σε κάθε επανάληψη συνδυασμού ένα outer και ένα inner στοιχείο όπου στην πρώτη επανάληψη το outer θα είναι ίσο με 1 και το inner ίσο με 6. Ο μετασχηματισμός του συνόλου γίνεται για όσο πλήθος στοιχείων ικανοποιούν και οι δυο πίνακες και δεν λαμβάνεται υπόψη μεμονωμένα κάποιος από τους δυο. Αυτό σημαίνει πως αν για παράδειγμα ο πίνακας Α είχε 6 στοιχεία και ο Β 7 στοιχεία τότε ο μετασχηματισμός θα συμπεριλάμβανε 6 στοιχεία όπου στον δεύτερο πίνακα το τελευταίο στοιχείο δεν θα έπαιρνε μέρος στην διαδικασία. Μπορούμε να χρησιμοποιήσουμε αντί για αλφαριθμητική εντολή, function με παραμέτρους τρείς μεταβλητές όπου η πρώτη είναι το outer στοιχείο, ή δεύτερη το inner, και η τρίτη το index της επανάληψης.

Αρχείο: zip.js

Enumerable.RangeDown(10,10).Zip(Enumerable.Range(1,10),"outer,inner=>outer + ':'+inner").ToArray();
Enumerable.RangeDown(10,10).Zip(Enumerable.Range(1,10),"outer,inner,index=>index + ':'+outer*inner").ToArray();

Αποτέλεσμα:

image

Where

Η εντολή Where είναι μια εντολή απομόνωσης στοιχείων σε ένα σύνολο δεδομένων μέσα από μία συγκεκριμένη είσοδο με δικά μας κριτήρια επιλογής. Αν θέλαμε για παράδειγμα μέσα από ένα σύνολο στοιχείων [11,12,13,14,15,16] να πάρουμε μέσα από αυτό ΜΟΝΟ όλους τους ζυγούς αριθμούς, η Where θα μας επιστρέψει έναν καινούργιο πίνακα 3 θέσεων με τα στοιχεία 12,14,16 να εμπεριέχονται μέσα σε αυτόν. Ο τρόπος λειτουργίας της είναι απλός για όσες επαναλήψεις επιστρέφεται τιμή true μέσα από τα κριτήρια επιλογής μας τότε το στοιχείο αυτό που αντιστοιχείται στην εκάστοτε επανάληψη επιλέγεται ως μέρος του νέου συνόλου που θα επιστραφεί, όσα αποτελέσματα επιστρέφονται με false τότε απορρίπτονται από την επιλογή. Στα παρακάτω παραδείγματα, στο πρώτο επιλέγουμε μόνο τους ζυγούς αριθμούς, ενώ στην δεύτερη περίπτωση επιλέγουμε όλους εκείνους τους αριθμούς που ο πολλαπλασιασμός τους με το index τους θα αποτελέσει μεγαλύτερο αριθμό από το 10.

Αρχείο: where.js

Enumerable.Range(11,5).Where("$%2==0").ToArray();
Enumerable.Range(11,5).Where(function(value,index){
    return value % 2 == 0;
}).ToArray();

Enumerable.Range(11,5).Where("value,index=>value*index>10").ToArray();
Enumerable.Range(11,5).Where(function(value,index){
    return value * index > 10;
}).ToArray();

Αποτέλεσμα:

image

CascadeBreadthFirst

Η CascadeBreadthFirst είναι μια εντολή μετατροπής ενός συνόλου από την μορφή δέντρου σε μορφή μονοδιάστατου πίνακα με βάση την διάσχιση των στοιχείων του δέντρου κατά πλάτος. Για το παρακάτω παράδειγμα θα χρησιμοποιήσουμε ένα σύνολο δεδομένων το οποίο περιλαμβάνει τα στοιχεία ενός γενεαλογικού δέντρου μιας οικογένειας ξεκινώντας από δυο αδέρφια τον Νικόλα και την Μαρία. Κάθε αντικείμενο διαθέτει ένα property, name που συμβολίζει το όνομα του ατόμου, ένα property, age που συμβολίζει την ηλικία του ατόμου, και ένα property childs που συμβολίζει τα παιδιά του συγκεκριμένου ατόμου.

Αρχείο: CascadeBreadthFirst.js

var arr = [
 { name: "Νικόλας", age: 100 , childs:[
  {name: "Δημήτριος", age: 60, childs:[
   {name:"Παντελής", age: 40, childs:[]},
   {name:"Δέσποινα", age:35, childs:[]}
  ] },
  {name: "Γεώργιος", age: 65 , childs:[]}
 ]},
 { name: "Μαρία", age: 80, childs: [
  {name:"Ιωάννα", age: 50, childs:[]},
  {name:"Δήμητρα", age: 60, childs:[]}
 ]}
];
Enumerable.From(arr).CascadeBreadthFirst("$.childs", "value,level=>value").ToArray();
Enumerable.From(arr).CascadeBreadthFirst(function(value){
    return value.childs;
}, function(value,level){
  return value;
}).ToArray();

Αποτέλεσμα:

[EIKONA]platos
image

CascadeDepthFirst

Η CascadeDepthFirst είναι μια εντολή μετατροπής ενός συνόλου από την μορφή δέντρου σε μορφή μονοδιάστατου πίνακα με βάση την διάσχιση των στοιχείων του δέντρου κατά βάθος. Για το παρακάτω παράδειγμα θα χρησιμοποιήσουμε ένα σύνολο δεδομένων το οποίο περιλαμβάνει τα στοιχεία ενός γενεαλογικού δέντρου μιας οικογένειας ξεκινώντας από δυο αδέρφια τον Νικόλα και την Μαρία. Κάθε αντικείμενο διαθέτει ένα property, name που συμβολίζει το όνομα του ατόμου, ένα property, age που συμβολίζει την ηλικία του ατόμου, και ένα property childs που συμβολίζει τα παιδιά του συγκεκριμένου ατόμου.

Αρχείο: CascadeDepthFirst.js

var arr = [
 { name: "Νικόλας", age: 100 , childs:[
  {name: "Δημήτριος", age: 60, childs:[
   {name:"Παντελής", age: 40, childs:[]},
   {name:"Δέσποινα", age:35, childs:[]}
  ] },
  {name: "Γεώργιος", age: 65 , childs:[]}
 ]},
 { name: "Μαρία", age: 80, childs: [
  {name:"Ιωάννα", age: 50, childs:[]},
  {name:"Δήμητρα", age: 60, childs:[]}
 ]}
];
Enumerable.From(arr).CascadeDepthFirst("$.childs", "value,level=>value").ToArray();
Enumerable.From(arr).CascadeDepthFirst(function(value){
    return value.childs;
}, function(value,level){
  return value;
}).ToArray();

Αποτέλεσμα:

vathos
image