Loda sh - как выбрать только один элемент из вложенного json? - PullRequest
7 голосов
/ 04 августа 2020

У меня есть вложенные данные о погоде json данные:

{
    "Temp": [{
            "time": "2020-08-04T12:00:00Z",
            "value": "12"
        },

        {
            "time": "2020-08-04T13:00:00Z",
            "value": "13"
        }
    ],
    "Humidity": [{
            "time": "2020-08-04T12:00:00Z",
            "value": "70"
        },

        {
            "time": "2020-08-04T13:00:00Z",
            "value": "73"
        }
    ]
}

Теперь (используя Loda sh или любую другую рекомендацию) задача состоит в том, чтобы как-то сгруппировать их по времени и выбрать только один элемент в время например:

{
    "data": [{
            "time": "2020-08-04T12:00:00Z",
            "Temprature": "12",
            "Humidity": "70"
        },
        {
            "time": "2020-08-04T13:00:00Z",
            "Temprature": "13",
            "Humidity": "73"
        }
    ]
}

Ответы [ 3 ]

1 голос
/ 04 августа 2020

const input={"Temp":[{"time":"2020-08-04T12:00:00Z","value":"12"},{"time":"2020-08-04T13:00:00Z","value":"13"}],"Humidity":[{"time":"2020-08-04T12:00:00Z","value":"70"},{"time":"2020-08-04T13:00:00Z","value":"73"}]}

const data = input.Temp.map(
   ({time, value: Temprature}) => ({
     time, 
     Temprature, 
     Humidity: input.Humidity.find(h => h.time === time).value
    }
));

console.log(data);
1 голос
/ 04 августа 2020

Используя lodash, вы можете сделать это так.

const data = {
    "Temp": [{
            "time": "2020-08-04T12:00:00Z",
            "value": "12"
        },

        {
            "time": "2020-08-04T13:00:00Z",
            "value": "13"
        }
    ],
    "Humidity": [{
            "time": "2020-08-04T12:00:00Z",
            "value": "70"
        },

        {
            "time": "2020-08-04T13:00:00Z",
            "value": "73"
        }
    ]
};

// Helper function to format an object
const formatObject = (key) => ({ time, value }) => ({ time, [key]: value });

const getData = () => {
    
    // Start a chain for the data object
    return _.chain(data)
        // Get the object entries
        .entries()
        // Map each key (eg. Temp) to its value
        // Spread operator used to produce the final array with depth 1
        .reduce((acc, [key, values]) => [...acc, ...values.map(formatObject(key))], [])
        // Group the data by time into an object
        .reduce((acc, val) => _.set(acc, val.time, _.merge(acc[val.time], val)), {})
        // Get the values
        .values()
        // Unwrap the value
        .value();
};

const result = {
    data: getData(),
};

console.log(result);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.19/lodash.min.js"></script>
1 голос
/ 04 августа 2020

Проверьте Object.entries(), Array.prototype.reduce() и для ... из для получения дополнительной информации.

// Input.
const input = {
  "temperature": [
    {"time": "2020-08-04T12:00:00Z", "value": "12"}, 
    {"time": "2020-08-04T13:00:00Z", "value": "13"}
  ],
  "humidity": [
    {"time": "2020-08-04T12:00:00Z", "value": "70"},
    {"time": "2020-08-04T13:00:00Z", "value": "73"}
  ]
}

// Zip Using Time.
const zipUsingTime = x => Object.entries(Object.entries(x).reduce((acc, [key, values], index) => {
  
  // Unpack Values.
  for (const y of values) {
    const {time, value} = y
    acc[time] = {...acc[time], [key]: value}
  }

  // ..
  return acc

}, {})).map(([time, props]) => ({time, ...props}))

// Output.
const output = {
  data: zipUsingTime(input)
}

// Proof.
console.log(output)
...