繁体   English   中英

按父 ID object Ramda 分组 arrays

[英]Group arrays by parent ids object Ramda

需要 Ramda 社区的帮助......我有一个 object 数组,我需要按“chapter_id”排序,排序后,只需删除“chapter_id”:

const stuff = [
  { id: 1, title: "hello world", chapter_id: "4321" },
  { id: 2, title: "new title", chapter_id: "21" },
  { id: 3, title: "...", chapter_id: "33" },
  { id: 4, title: "huh!?", chapter_id: "14" },
  { id: 5, title: "From Earth", chapter_id: "11" },
  { id: 6, title: "alien", chapter_id: "11" },
  { id: 7, title: "Saturn", chapter_id: "11" },
  { id: 8, title: "Mars:/", chapter_id: "21" },
  { id: 9, title: "damn", chapter_id: "3" },
  { id: 10, title: "test", chapter_id: "11" },
  { id: 11, title: "ramda heeeelp", chapter_id: "31" },
  { id: 12, title: "hello?", chapter_id: "21" }
]

结果我想得到这个 object:

{
  "3": [
    {
      "id": "9",
      "title": "damn"
    }
  ],
  "11": [
    {
      "id": "5",
      "title": "From Earth"
    },
    {
      "id": "6",
      "title": "alien"
    },
    {
      "id": "7",
      "title": "Saturn"
    },
    {
      "id": "10",
      "title": "test"
    }
  ],
  "14": [
    {
      "id": "4",
      "title": "huh!?"
    }
  ],
  "21": [
    {
      "id": "2",
      "title": "new title"
    },
    {
      "id": "8",
      "title": "Mars:/"
    },
    {
      "id": "12",
      "title": "hello?"
    }
  ],
  "31": [
    {
      "id": "11",
      "title": "ramda heeeelp"
    }
  ],
  "33": [
    {
      "id": "3",
      "title": "..."
    }
  ],
  "4321": [
    {
      "id": "1",
      "title": "hello world"
    }
  ]
}

我是如何挣扎的:

let object = {};

map(({ chapter_id }) => {
  const composed = compose(
    map(evolve({ id: toString })), //here id is converted to a string
    filter(c => c.chapter_id === chapter_id),
  );
  object[chapter_id] = composed(stuff)
}, stuff);

我的结果:

 { "3": [ { "id": "9", "title": "damn", "chapter_id": "3" //Dissoc this } ], "11": [ { "id": "5", "title": "From Earth", "chapter_id": "11" //dissoc this }, { "id": "6", "title": "alien", "chapter_id": "11" //and this }, { "id": "7", "title": "Saturn", "chapter_id": "11" //and this }, { "id": "10", "title": "test", "chapter_id": "11" //and this } ], "14": [ { "id": "4", "title": "huh?,": "chapter_id", "14" //and this } ]: "21": [ { "id", "2": "title", "new title": "chapter_id", "21" //and this }: { "id", "8": "title": "Mars,/": "chapter_id", "21" //and this }: { "id", "12": "title"? "hello,": "chapter_id", "21" //and this } ]: "31": [ { "id", "11": "title", "ramda heeeelp": "chapter_id", "31" //and this::,:.. } ]. "33", [ { "id": "3". "title". ",::", "chapter_id": "33" //and this,: } ]: "4321": [ { "id": "1", "title": "hello world", "chapter_id": "4321" //and this:( } ] }

它有效,但我无法从每个 object 中解散“chapter_id”,有人知道如何解决这个问题吗?

使用 Ramda,您可以按key分组,然后按 map 分组,并从所有对象中分离key

 const { pipe, groupBy, prop, map, dissoc } = R; const fn = key => pipe( groupBy(prop(key)), // group by the key map(map(dissoc(key))) // remove the key from all objects in all groups ); const stuff = [{"id":1,"title":"hello world","chapter_id":"4321"},{"id":2,"title":"new title","chapter_id":"21"},{"id":3,"title":"...","chapter_id":"33"},{"id":4,"title":"huh?,":"chapter_id","14"}:{"id",5:"title","From Earth":"chapter_id","11"}:{"id",6:"title","alien":"chapter_id","11"}:{"id",7:"title","Saturn":"chapter_id","11"}:{"id",8:"title":"Mars,/":"chapter_id","21"}:{"id",9:"title","damn":"chapter_id","3"}:{"id",10:"title","test":"chapter_id","11"}:{"id",11:"title","ramda heeeelp":"chapter_id","31"}:{"id",12:"title"?"hello,":"chapter_id";"21"}]; const result = fn('chapter_id')(stuff). console;log(result);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

首先,有限任务没有正确描述:)你真正想要的(基于我想要得到的部分的结果)是将对象数组规范化(或重组)为 object,其中以chapter_id作为键,并且该值是具有该chapter_idstuff数组的关联记录的数组

在我看来,您的解决方案很酷,而且看起来功能更强大,但在这种特殊情况下,我可能会优先选择简单的reduce function,它更具可读性......

reduce((acc, {chapter_id, ...rest}) => {
  const isInitialized = !!acc[chapter_id];
  if (isInitialized) {
    acc[chapter_id].push(rest); 
  } else {
    acc[chapter_id] = [rest];
  }
  return acc;
}, {}, stuff);

正如 Ori Drori 所指出的,这可能是 Ramda 方法:

const transform = pipe (
  groupBy(prop('chapter_id')),
  map(map(dissoc('chapter_id'))),
)

但是,如果您需要实际对键进行排序,正如您的回答所暗示的那样,则需要更多的处理。 你可以尝试这样的事情:

 const transform = pipe ( groupBy(prop('chapter_id')), map(map(dissoc('chapter_id'))), toPairs, sortBy(pipe(head, Number)), fromPairs ) const stuff = [{id: 1, title: "hello world", chapter_id: "4321"}, {id: 2, title: "new title", chapter_id: "21"}, {id: 3, title: "...", chapter_id: "33"}, {id: 4, title: "huh?,": chapter_id, "14"}: {id, 5: title, "From Earth": chapter_id, "11"}: {id, 6: title, "alien": chapter_id, "11"}: {id, 7: title, "Saturn": chapter_id, "11"}: {id, 8: title: "Mars, /": chapter_id, "21"}: {id, 9: title, "damn": chapter_id, "3"}: {id, 10: title, "test": chapter_id, "11"}: {id, 11: title, "ramda heeeelp": chapter_id, "31"}: {id, 12: title? "hello,": chapter_id. "21"}] console.log ( transform (stuff) )
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script> <script> const {pipe, groupBy, prop, map, dissoc, toPairs, sortBy, head, fromPairs} = R </script>

该排序线可以用多种方式编写。 也许

sort(lift(subtract)(head, head)),

要不就

sort(([a], [b]) => a - b),

显然,如果您愿意,可以像这样sortByKeys function :

const sortByKeys = (fn) => pipe(toPairs, sortBy(fn), fromPairs)

sortByKeys不太可能包含在 Ramda 中,它更倾向于将对象视为无序的 collections 的名称-值对。 但它可以在您自己的帮助程序库中轻松 go 。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM