按特定值分组JSON对象的最佳方法是什么?

时间:2018-08-11 10:26:57

标签: javascript json reactjs

我希望能够像这样在React应用程序中显示数据:

Today
- Batman entered the watchtower at 10:30am
- Batman entered the watchtower at 10:15am
- Wonder Woman entered the watchtower at 10:00am

Yesterday
- Flash entered the watchtower at 10:30am
- Green Lantern entered the watchtower at 10:15am
- Cyborg entered the watchtower at 10:00am

9th August 2018
- Aquaman entered the watchtower at 10:30am

发送给我的数据是 JSON 对象数组:

[{
    "name": "Batman",
    "secret_identity": "Bruce Wayne",
    "timestamp": "1533983400" // Epoch timestamp equating to 11th August 2018 at 10:30am
},
{
    "name": "Superman",
    "secret_identity": "Clark Kent",
    "timestamp": "1533982500" // Epoch timestamp equating to 11th August 2018 at 10:15am
},
{
    "name": "Wonder Woman",
    "secret_identity": "Diana Prince",
    "timestamp": "1533981600" // Epoch timestamp equating to 11th August 2018 at 10:00am
},
{
    "name": "Flash",
    "secret_identity": "Wally West",
    "timestamp": "1533897000" // Epoch timestamp equating to 10th August 2018 at 10:30am
},
{
    "name": "Green Lantern",
    "secret_identity": "Hal Jordan",
    "timestamp": "1533896100" // Epoch timestamp equating to 10th August 2018 at 10:15am
},
{
    "name": "Cyborg",
    "secret_identity": "Victor Stone",
    "timestamp": "1533895800" // Epoch timestamp equating to 10th August 2018 at 10:00am
},
{
    "name": "Aquaman",
    "secret_identity": "Arthur Curry",
    "timestamp": "1533810600" // Epoch timestamp equating to 9th August 2018 at 10:30am
}]

我不确定使用此 JSON 数组以所需方式呈现数据的最佳方法是什么。我以为我可能需要像下面这样的新对象进一步处理数据,但不确定最好的处理方式。

[{
    "11-August-2018" : [{
        "name": "Batman",
        "secret_identity": "Bruce Wayne",
        "timestamp": "1533983400" // 11th August 2018 at 10:30am
    },
    {
        "name": "Superman",
        "secret_identity": "Clark Kent",
        "timestamp": "1533982500" // 11th August 2018 at 10:15am
    },
    {
        "name": "Wonder Woman",
        "secret_identity": "Diana Prince",
        "timestamp": "1533981600" // 11th August 2018 at 10:00am
    }],
    "10-August-2018" : [{
        "name": "Flash",
        "secret_identity": "Wally West",
        "timestamp": "1533897000" // 10th August 2018 at 10:30am
    },
    {
        "name": "Green Lantern",
        "secret_identity": "Hal Jordan",
        "timestamp": "1533896100" // 10th August 2018 at 10:15am
    },
    {
        "name": "Cyborg",
        "secret_identity": "Victor Stone",
        "timestamp": "1533895800" // 10th August 2018 at 10:00am
    }],
    "09-August-2018" : [{
        "name": "Aquaman",
        "secret_identity": "Arthur Curry",
        "timestamp": "1533810600" // 9th August 2018 at 10:30am
    }]
}]

5 个答案:

答案 0 :(得分:0)

例如,您可以使用reduce函数对数据进行分组,也可以自己格式化日期对象,或者如果以后需要一些复杂的格式,则可以使用 moment.js 库( “今天”,“昨天”,“第”,“第”等)。因此,在我的示例中,我没有映射月份名称,只使用了UTC:

let data = [{
    "name": "Batman",
    "secret_identity": "Bruce Wayne",
    "timestamp": "1533983400" // Epoch timestamp equating to 11th August 2018 at 10:30am
},
{
    "name": "Superman",
    "secret_identity": "Clark Kent",
    "timestamp": "1533982500" // Epoch timestamp equating to 11th August 2018 at 10:15am
},
{
    "name": "Wonder Woman",
    "secret_identity": "Diana Prince",
    "timestamp": "1533981600" // Epoch timestamp equating to 11th August 2018 at 10:00am
},
{
    "name": "Flash",
    "secret_identity": "Wally West",
    "timestamp": "1533897000" // Epoch timestamp equating to 10th August 2018 at 10:30am
},
{
    "name": "Green Lantern",
    "secret_identity": "Hal Jordan",
    "timestamp": "1533896100" // Epoch timestamp equating to 10th August 2018 at 10:15am
},
{
    "name": "Cyborg",
    "secret_identity": "Victor Stone",
    "timestamp": "1533895800" // Epoch timestamp equating to 10th August 2018 at 10:00am
},
{
    "name": "Aquaman",
    "secret_identity": "Arthur Curry",
    "timestamp": "1533810600" // Epoch timestamp equating to 9th August 2018 at 10:30am
}]

let result = data.reduce((acc, item) => {
    let date = new Date(item.timestamp*1000);
    let key = `${date.getUTCDate()}-${date.getUTCMonth()+1}-${date.getUTCFullYear()}`;
    if (!acc[key]) {
        acc[key] = [];
    }
    acc[key].push(item);
    return acc;
}, {})

console.log(result)

答案 1 :(得分:0)

您要在此处解决两个较小的问题:

  • 迄今映射时代
  • 按日期对事件进行分组

我将使用实用程序库ramda简化答案,但是如果您愿意,可以实现自己的groupBy函数。

可能的解决方案:

const epochToDate = epoch => {
  const date = new Date(epoch)
  return `${date.getDate()}-${date.getMonth() + 1}-${date.getFullYear()}`
}
const groupedJson = R.groupBy(
  event => epochToDate(parseInt(event.timestamp, 10)),
  rawJson
)

您可以在ramda repl中玩它。

答案 2 :(得分:0)

u必须像这样将json文件导入到您的react应用程序

import data from './data.json'

this.data = data

并像其他任何对象一样使用它

答案 3 :(得分:0)

排序,映射,减少。要爱es2018

(d => {
  // a few utility methods
  const dateFromEpoch = epochStr => new Date(new Date(0).setUTCSeconds(+epochStr));
  const padLeft = n => `${n}`.padStart(2, "0");
  const removeTime = dateTime => new Date(dateTime.toISOString().split("T")[0]);
  const getDateLabel = dateTime => {
    const now = removeTime(new Date());
    const plainDate = removeTime(dateTime);
    const dayDiff = Math.abs(Math.round(((plainDate - now) / 3600000) / 24));
    return dayDiff < 1 ?
      "Today" :
      	dayDiff === 1 ?
      	"Yesterday" :
      	`${dayDiff} Days ago`;
  };

  const heroicData = getHeroicData()
    .sort((a, b) => +a.timestamp < +b.timestamp) // sort descending
    .reduce(heroicReducer, {});                  // create reshuffled object

  // the heroic entry points
  d.querySelector("#raw").textContent = JSON.stringify(heroicData, null, " ");

  // create html output using a reducer
  d.querySelector("#result").innerHTML = Object.keys(heroicData)
    .reduce((reduced, day) =>
      reduced.concat(`
        <b>${day}</b>
        <ul>
          ${heroicData[day].map(visit => `<li>${visit}</li>`).join("")}
        </ul>`), [])
    .join("");

  function heroicReducer(reduced, heroicVisit) {
    const dateTime = dateFromEpoch(heroicVisit.timestamp);
    const reportKey = getDateLabel(dateTime);
    const reportString = `<heroe>${
    		heroicVisit.name}</heroe> entered the watchtower at ${
        	padLeft(dateTime.getHours())}:${
        		padLeft(dateTime.getMinutes())}`;
    if (reduced[reportKey]) {
      reduced[reportKey].push(reportString)
    } else {
      reduced[reportKey] = [reportString];
    }
    return reduced;
  }

  function getHeroicData() {
    return [{
        "name": "Batman",
        "secret_identity": "Bruce Wayne",
        "timestamp": "1533983400"
      },
      {
        "name": "Superman",
        "secret_identity": "Clark Kent",
        "timestamp": "1533982500"
      },
      {
        "name": "Wonder Woman",
        "secret_identity": "Diana Prince",
        "timestamp": "1533981600"
      },
      {
        "name": "Flash",
        "secret_identity": "Wally West",
        "timestamp": "1533897000"
      },
      {
        "name": "Green Lantern",
        "secret_identity": "Hal Jordan",
        "timestamp": "1533896100"
      },
      {
        "name": "Cyborg",
        "secret_identity": "Victor Stone",
        "timestamp": "1533895800"
      },
      {
        "name": "Aquaman",
        "secret_identity": "Arthur Curry",
        "timestamp": "1533810600"
      }
    ];
  }
})(document);
body {
  font: normal 12px/15px verdana, arial;
  margin: 3em;
}

heroe {
  color: red;
  font-style: italic;
}
<pre id="raw"></pre>
<h3>**Reduced to output</h3>
<div id="result"></div>

答案 4 :(得分:0)

    outJSON= [ {team: "TeamA",name: "Ahmed",field3:"val3"}, {team: "TeamB",name: "Ahmed",field3:"val43"}, {team: "TeamA",name: "Ahmed",field3:"val55"} ]

var groupBy = function(xs, key) {
  return xs.reduce(function(rv, x) {
    (rv[x[key]] = rv[x[key]] || []).push(x);
    return rv;
  }, {});
};
var groubedByTeam=groupBy(outJSON, 'team')
console.log(groubedByTeam);