组合匹配的对象数组

时间:2017-10-20 23:45:29

标签: javascript arrays lodash arr

我正在尝试将项目中的嵌套对象与相同的键组合在一起。

  • 查找重复的“顶级”值
  • 将重复的“顶级”项目合并为一个对象(包括他们的孩子。
  • 'type'数组中应该没有重复值

我在这里试了https://jsfiddle.net/Lpq6huvw/410/

输入数据:

Set {
  Object {
    "UserData": "/db/UserData/509c404f-ffa1-49d3-a161-b9eb5b2ebb14",
    "UserDataPrivate": "/db/UserDataPrivate/26b7d879-4403-4135-ab44-b23e5244606b",
    "UserStatus": "/db/UserStatus/cb50eae0-e254-4d8c-915a-674fd314fff3",
    "createdAt": "2017-10-20T21:03:26.575Z",
    "id": "/db/User/68",
    "inactive": null,
    "updatedAt": "2017-10-20T23:34:12.179Z",
    "username": "15031111234",
    "version": 4,
  },
  Object {
    "UserData": "/db/UserData/a3dded63-4e0b-4841-b201-4c96dad1844d",
    "UserDataPrivate": "/db/UserDataPrivate/6037a718-e33f-4945-b2d0-ca4c11fa4f13",
    "UserStatus": null,
    "createdAt": "2017-09-21T18:26:31.089Z",
    "id": "/db/User/10",
    "inactive": false,
    "updatedAt": "2017-10-18T20:10:06.681Z",
    "username": "15038304313",
    "version": 19,
  },
}

var searchbyID = propEq('id', '/db/User/10');
result = filter(searchbyID, test);
console.log(result)

进入这个数组:

public class MapsActivityy extends FragmentActivity implements  OnMapReadyCallback {

private GoogleMap mMap;
LocationManager locationManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps_activityy);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
    //Permission to view el location
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                 int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }
    //check lw el network provider enabled
    //example vodafone or wi-fi
    if(locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                //bngeeb el actual location
                double latitude = location.getLatitude();
                double longitude = location.getLongitude();
                // latlng el location 3la el map
                LatLng latLng = new LatLng(latitude,longitude);
                //initalize class geocoder te3ml convert mn el lat wl lng to an address
                Geocoder geocoder = new Geocoder(getApplicationContext());
                try {
                    // 3shan n7ot el address fe list w max el results 1
                    List<Address> addressList= geocoder.getFromLocation(latitude,longitude,1);
                    String string  = addressList.get(0).getCountryName()+" , ";
                    string +=addressList.get(0).getLocality()+" , ";
                    string +=addressList.get(0).getSubLocality();
                    //Hy7ot marker 3l location
                    mMap.addMarker(new MarkerOptions().position(latLng).title(string));
                    //3shan n3ml zoom 3l location
                    // el second val hwa amount of zoom
                    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,15.2f));

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onStatusChanged(String s, int i, Bundle bundle) {
            }
            @Override
            public void onProviderEnabled(String s) {
            }
            @Override
            public void onProviderDisabled(String s) {
            }
        });
    }
    //Satellite
    else if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {

                    //bngeeb el actual location
                    double latitude = location.getLatitude();
                    double longitude = location.getLongitude();
                    // latlng el location 3la el map
                    LatLng latLng = new LatLng(latitude,longitude);
                    //initalize class geocoder te3ml convert mn el lat wl lng to an address
                    Geocoder geocoder = new Geocoder(getApplicationContext());
                    try {
                        // 3shan n7ot el address fe list w max el results 1
                        List<Address> addressList= geocoder.getFromLocation(latitude,longitude,1);
                        String string  = addressList.get(0).getCountryName()+" , ";
                        string +=addressList.get(0).getLocality()+" , ";
                        //if available hygeeb subLoc if not hyb3t null
                       string +=addressList.get(0).getSubLocality();
                        //Hy7ot marker 3l location
                        mMap.addMarker(new MarkerOptions().position(latLng).title(string));
                        //3shan n3ml zoom 3l location
                        // el second val hwa amount of zoom
                        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,15.2f));

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }


            @Override
            public void onStatusChanged(String s, int i, Bundle bundle) {

            }

            @Override
            public void onProviderEnabled(String s) {

            }

            @Override
            public void onProviderDisabled(String s) {

            }
        });

    }
}


/**
 * Manipulates the map once available.
 * This callback is triggered when the map is ready to be used.
 * This is where we can add markers or lines, add listeners or move the camera. In this case,
 * we just add a marker near Sydney, Australia.
 * If Google Play services is not installed on the device, the user will be prompted to install
 * it inside the SupportMapFragment. This method will only be triggered once the user has
 * installed Google Play services and returned to the app.
 */
@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    // Add a marker in Sydney and move the camera
 /*  LatLng sydney = new LatLng(-34, 151);
    mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
    mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));*/

}
}

我在下面尝试了这个,它将所有重复的项目映射为一个对象。但是,我希望它在每个“顶级”前身下映射。

[{
    "a": "Mon",
    "type": [{
        "b": 1
    }, {
        "b": 3
    }]
}, {
    "a": "Mon",
    "type": [{
        "b": 2
    }]
}, {
    "a": "Tue",
    "type": [{
        "b": 40
    }]
}, {
    "a": "Tue",
    "type": [{
        "b": 50
    }]
}, {
    "a": "Wed",
    "type": [{
        "b": 30
    }]
}]

3 个答案:

答案 0 :(得分:2)

我个人认为Javascript内置的函数运行良好,并且比一些lodash函数更容易理解。

例如

&#13;
&#13;
var data = [{"a":"Mon","type":[{"b":1},{"b":3}]},{"a":"Mon","type":[{"b":2},{"b":3}]},{"a":"Tue","type":[{"b":40}]},{"a":"Tue","type":[{"b":50}]},{"a":"Wed","type":[{"b":30}]}];

    
var result = data.reduce((acc, val) => {
  var found = acc.find((findval) => val.a === findval.a);
  if (!found) acc.push(val)
  else found.type = found.type.concat(
    val.type.filter((f) => !found.type.find((findval) => f.b === findval.b)));
  return acc;
}, []);
 
console.log(result);
&#13;
&#13;
&#13;

答案 1 :(得分:1)

这是一个没有lodash的答案:

function combine (input) {
  const hash = input.reduce((result, current) => {
    if (result[current['a']]) {
      result[current['a']] = result[current['a']].concat(current['type'])
    } else {
      result[current['a']] = current['type']
    }

    return result
  }, {})

  return Object.keys(hash).map(key => {
    return {
      a: key,
      type: hash[key]
    }
  })
}

答案 2 :(得分:1)

ES6 :您可以使用Array#reduce进行迭代,将项目收集到Map中,然后使用扩展语法和Map#值转换回数组:

&#13;
&#13;
const data = [{"a":"Mon","type":[{"b":1},{"b":3}]},{"a":"Mon","type":[{"b":2}]},{"a":"Tue","type":[{"b":40}]},{"a":"Tue","type":[{"b":50}]},{"a":"Wed","type":[{"b":30}]}];

const result = [...data.reduce((m, { a, type }) => {
  const item = m.get(a) || { a, type: [] }; // use a Set to maintain uniqueness
  
  item.type.push(...type);
  
  return m.set(a, item);
}, new Map).values()]
.map(({ a, type }) => ({ // make types unique again
  a, 
  type: [...type.reduce((m, o) => m.has(o.b) ? m : m.set(o.b, o), new Map).values()]
}));


console.log(result);
&#13;
&#13;
&#13;

Lodash :使用_.groupBy()在一个组中获取具有相同a属性的所有对象。映射组,并使用_.mergeWith()合并每个组,并连接所有type数组。 使用map进行另一次传递,以使type数组中的所有项目都是唯一的。

&#13;
&#13;
const data = [{"a":"Mon","type":[{"b":1},{"b":3}]},{"a":"Mon","type":[{"b":2}]},{"a":"Tue","type":[{"b":40}]},{"a":"Tue","type":[{"b":50}]},{"a":"Wed","type":[{"b":30}]}];


const result = _(data)
  .groupBy('a')
  .map((group) => _.mergeWith({}, ...group, ((objValue, srcValue, key) =>
    key === 'type' ? (objValue || []).concat(srcValue) : undefined
  )))
  .map((obj) => Object.assign(obj, { type: _.uniq(obj.type) }))
  .value();

console.log(result);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
&#13;
&#13;
&#13;