JS - Lodash;嵌套对象(父/子)到平面数组

时间:2014-06-02 16:46:04

标签: javascript arrays nested javascript-objects lodash

我正在使用lodash(虽然解决方案没有必要),我想转换以下结构:

{ prop1: 'root',
  prop2: 'someVal',
  children: [
    { prop1: 'first Child',
      prop2: 'some other val',
      children: [
        { prop1: 'last child'
          prop2: 'another value'
          children: []
        }
      ]
    }
  ]
}

到平面阵列:

[ { prop1: 'root', prop2: 'someVal' }, 
  {prop1: 'firstChild', prop2: 'some Other Val'}, 
  {prop1: 'last child', prop2: 'another value'}
]

深度可能会有所不同,最后一个孩子将始终[]分配给其children属性;请注意,在该特定情况下,children数组将始终包含单个项目

应该相当简单,但似乎我出于某些原因无法指责它

由于

4 个答案:

答案 0 :(得分:1)

解决了这个片段(在CoffeeScript中)

flatten = (node) ->
        row = node
        _.each node.children or [], (el) ->
            flatten el
        ancestors.push row

答案 1 :(得分:0)

使用纯JS的解决方案: - http://jsbin.com/bazilurolu/edit?js,console

var flatArray = function(input){
    var result = [];
    (function(obj){
        var arr = [], newObj = {};
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                if(key !== "children"){
                    newObj[key] = obj[key];
                }
                else{
                    arr = obj[key];
                }
            }
        }
        result.push(newObj);
        if(arr.length){
            arguments.callee(arr[0]);
        }
    })(input);
    return result;
};

答案 2 :(得分:0)

这是使用匿名目标展平(例如flattened

flatten = (collection, flattened = [])->
  _.each collection, (obj)->
    flattened.push obj
    flatten obj.children, flattened
  flattened

答案 3 :(得分:0)

这是@jusopi 解决方案的打字稿版本

#include <iostream>
#include <stdio.h>
#include <stdexcept>
#include <vector>
#include <cmath>
#include <algorithm>
#include <time.h>
#include <random>

template<typename T>
class MetricSpace {
public:
    virtual double distance(const T& point1, const T& point2) = 0;

    double calculateEccentricity(size_t pointIndex, double r) {
        double sum{0};
        size_t N = points_.size();

        std::cout << "Amount of points in calculateEccentricity: " << N << std::endl;

        for (size_t i = 0; i < N; i++) {
            std::cout << distance(points_[pointIndex], points_[i]) << std::endl;
            sum += std::pow(distance(points_[pointIndex], points_[i]), r);
        }

        return std::pow(sum/N, 1/r);
    }

protected:
    std::vector<T> points_;
};

template<size_t n>
class Rn : public MetricSpace<std::vector<double>> {
public:

    // Constructor
    Rn(std::vector<std::vector<double>> points) {
        points_ = points;
    }

    // Distance function
    double distance(const std::vector<double>& point1, const std::vector<double>& point2) {
        double squaredDistance{0};

        for (size_t i = 0; i < n; i++) {
            squaredDistance += (point1[i] - point2[i])*(point1[i] - point2[i]);
        }

        return std::sqrt(squaredDistance);
    }

    size_t getAmountOfPoints() {
        return points_.size();
    }

private:
    std::vector<std::vector<double>> points_;
};

template<size_t m>
Rn<m> RnMaker(long numberOfPoints) {

    std::vector<std::vector<double>> points;

    // Setting up the random machine
    double lowerBound = 0;
    double upperBound = 10;
    std::uniform_real_distribution<double> uniform(lowerBound, upperBound);
    std::default_random_engine randomEngine;

    // Creating the random points
    for (long i = 0; i < numberOfPoints; i++) {
        std::vector<double> point;
        for (int j = 0; j < m; j++) {
            point.push_back(uniform(randomEngine));
        }
        points.push_back(point);
    }

    return Rn<m>(points);
}

int main() {
    Rn<3> space = RnMaker<3>(100);

    std::cout << "Space has " << space.getAmountOfPoints() << " points." << std::endl;

    double answer = space.calculateEccentricity(10, 2.1);

    std::cout << "Eccentricity of the 10'th point in R^n with r = 2.1: " << answer << std::endl;
}