反向遍历层次结构

时间:2020-01-16 00:13:18

标签: javascript arrays typescript ecmascript-5

我有一个对象层次结构,其中包含父ID。我像这样解析json对象时,将parentId添加到子对象中。

library(data.table)
df[, paste0(rep(c("mean.", "sum."), each = 2),  vars) := 
       c(lapply(.SD, mean), lapply(.SD, sum)), by = .(city), .SDcols = vars]
df
#    rain temp skip windw_sz city ord mean.rain mean.temp sum.rain sum.temp
# 1:    5    1    0        2    a   2         5         3       25       15
# 2:    5    2    1        1    a   5         5         3       25       15
# 3:    5    3    2        2    a   3         5         3       25       15
# 4:    5    4    2        1    a   4         5         3       25       15
# 5:    5    5    2        2    a   1         5         3       25       15
# 6:    5    6    0        1    b   2         5         8       25       40
# 7:    5    7    2        2    b   5         5         8       25       40
# 8:    5    8    1        2    b   3         5         8       25       40
# 9:    5    9    2        1    b   4         5         8       25       40
#10:    5   10    2        2    b   1         5         8       25       40

如果我有孙子孙女,有没有想到如何拔掉祖先?

数据在模拟袋装(Ancestries.json)上

作为示例,使用以下json和 mFusedLocationClient.getLastLocation() .addOnSuccessListener(this, new OnSuccessListener<Location>() { @Override public void onSuccess(final Location location) { // Got last known location. In some rare situations this can be null. if (location != null) { // Logic to handle location object Double latittude = location.getLatitude(); Double longitude = location.getLongitude(); String uid = FirebaseAuth.getInstance().getCurrentUser().getUid(); DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference("Users"); DatabaseReference update = rootRef.child(uid); GeoFire geoFire=new GeoFire(rootRef); geoFire.setLocation("latandlong", new GeoLocation(location.getLatitude(), location.getLongitude()), new GeoFire.CompletionListener() { @Override public void onComplete(String key, DatabaseError error) { if (error != null) { System.err.println("There was an error saving the location to GeoFire: " + error); } else { System.out.println("Location saved on server successfully!"); } } }); geoFire.getLocation("latandlong", new LocationCallback() { @Override public void onLocationResult(String key, GeoLocation location) { if (location != null) { System.out.println(String.format("The location for key %s is [%f,%f]", key, location.latitude, location.longitude)); // save longitude and latitude to db String uid = FirebaseAuth.getInstance().getCurrentUser().getUid(); DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference(); DatabaseReference update = rootRef.child("Users").child(uid); Double longi = location.longitude; Double lat = location.latitude; update.child("latandlong").setValue(location.latitude+ "," +location.longitude); //update.child("longitude").setValue(longi); //update.child("latitude").setValue(lat); } else { System.out.println(String.format("There is no location for key %s in GeoFire", key)); } } @Override public void onCancelled(DatabaseError databaseError) { System.err.println("There was an error getting the GeoFire location: " + databaseError); } }); protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_news_feed); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR); menuItem=(MenuItem)findViewById(R.id.item_sign_in); mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this); recycler=findViewById(R.id.recyclerView); recycler.setLayoutManager(new LinearLayoutManager(this)); final DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference(); mFusedLocationClient.getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() { @Override public void onSuccess(Location location) { Double lat=location.getLatitude(); Double longi=location.getLongitude(); firebaseDatabase=FirebaseDatabase.getInstance().getReference("Users"); GeoFire geoFire=new GeoFire(firebaseDatabase.child("latandlong")); GeoQuery geoQuery=geoFire.queryAtLocation(new GeoLocation(lat,longi),5); geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() { @Override public void onKeyEntered(String key, GeoLocation location) { firebaseDatabase.child(key).addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { if(dataSnapshot.exists()){ list=new ArrayList<UserInformation>(); for(DataSnapshot dataSnapshot1:dataSnapshot.getChildren()){ UserInformation uuu=dataSnapshot1.getValue(UserInformation.class); list.add(uuu); } } adapter=new MyAdapter(NewsFeedActivity.this,list); recycler.setAdapter(adapter); } @Override public void onCancelled(@NonNull DatabaseError databaseError) { } }); } @Override public void onKeyExited(String key) { } @Override public void onKeyMoved(String key, GeoLocation location) { } @Override public void onGeoQueryReady() { } @Override public void onGeoQueryError(DatabaseError error) { } }); } }); ,我将创建并使用以下ID进行数组

['5','0723','133','1']

public static fromJson(json: any): Ancestry | Ancestry[] {
    if (Array.isArray(json)) {
      return  json.map(Ancestry.fromJson) as Ancestry[];
    }

    const result = new Ancestry();
    const { parents } = json;

    parents.forEach(parent => {
      parent.parentId = json.id;
    });

    json.parents = Parent.fromJson(parents);
    Object.assign(result, json);
    return result;
  }

1 个答案:

答案 0 :(得分:0)

也许有很多方法可以解决此问题,但是我认为最简单的方法是简单地在数据结构中进行搜索,并以与找到ID时相反的顺序存储ID。这样,输出就是您想要的。

您还可以颠倒其他方法的顺序。

我想指出,json-结构有点奇怪。我希望它只是嵌套了children数组,而不是将它们重命名为parentchildrengrandchildren

let data = [{
  "id": "1",
  "name": "Deer, spotted",
  "parents": [
    {
      "id": "133",
      "name": "Jaime Coldrick",
      "children": [
        {
          "id": "0723",
          "name": "Ardys Kurten",
          "grandchildren": [
            {
              "id": "384",
              "name": "Madelle Bauman"
            },
            {
              "id": "0576",
              "name": "Pincas Maas"
            },
            {
              "id": "5",
              "name": "Corrie Beacock"
            }
          ]
        }]
    }]
}]

const expectedResults =  ['5', '0723', '133', '1']

function traverseInverseResults(inputId, childArray) {
    if(!childArray){ return }
    for (const parent of childArray) {
        if(parent.id === inputId){
            return [parent.id]
        } else {
            let res = traverseInverseResults(inputId, parent.parents || parent.children || parent.grandchildren) // This part is a bit hacky, simply to accommodate the strange JSON structure.
            if(res) {
                res.push(parent.id)
                return res
            }
        }
    }
    return
}
let result = traverseInverseResults('5', data)
console.log('results', result)
console.log('Got expected results?', expectedResults.length === result.length && expectedResults.every(function(value, index) { return value === result[index]}))