无法减少数组中的相关JavaScript对象

时间:2018-02-26 09:42:32

标签: javascript json ecmascript-6

我正在尝试按键对数组中的相关JavaScript对象进行分组。

但是,我已经陷入了困境。

我有一个像这样的JavaScript对象数组:

[
    {
        "text": "hello world",
        "startPos": 0,
        "endPos": 12,
        "value": "hello world",
        "entity": "Greeting"
    },
    {
        "text": "hello world",
        "startPos": 0,
        "endPos": 6,
        "value": "hello",
        "entity": "Greeting"
    }
]

我制作了以下代码,但我被卡住了。



a = [
  {
    "text": "hello world",
    "startPos": 0,
    "endPos": 12,
    "value": "hello world",
    "entity": "Greeting"
  },
  {
    "text": "hello world",
    "startPos": 0,
    "endPos": 6,
    "value": "hello",
    "entity": "Greeting"
  }
]

let result = a.reduce((acc, d) => {
  const found = acc.find(a => a.text == d.text);
  const entitiesArray = {
    startPos: d.startPos,
    endPos: d.endPos,
    entity: d.entity
  };
  if (found) {
    found.entities.push(entitiesArray);
  } else {
    acc.push({});
  }
  return acc;
}, []);

console.log(JSON.stringify(result, undefined, 4));




基于"text"键重复JavaScript对象。我想基于"text"键将上面的数组分组到一个对象中。

这样的事情:

[
    {
        "text": "hello world",
        "entities": [
                {
                    "startPos": 0,
                    "endPos": 12,
                    "value": "hello world",
                    "entity": "Greeting"
                },
                {
                    "startPos": 0,
                    "endPos": 6,
                    "value": "hello",
                    "entity": "Greeting"
                }
        ]
    }
]

3 个答案:

答案 0 :(得分:2)

text为false时,您错过了将带有found的对象添加到数组中。因此,在下一次迭代中,它无法找到比较文本的对象

此外,如果您的IDE和引擎支持新的ES提案,则可以使用Rest/Spread Properties

const a = [
  {
    "text": "hello world",
    "startPos": 0,
    "endPos": 12,
    "value": "hello world",
    "entity": "Greeting"
  },
  {
    "text": "hello world",
    "startPos": 0,
    "endPos": 6,
    "value": "hello",
    "entity": "Greeting"
  }
]

let result = a.reduce((acc, d) => {
  const found = acc.find(a => a.text == d.text);
  
  const { text, ...entitiesArray } = { ...d }; // <- Rest/Spread properties
  
  found ? found.entities.push(entitiesArray) 
        : acc.push({ text: d.text, entities: [entitiesArray]})

  return acc;
}, []);

console.log(result);

答案 1 :(得分:2)

您还可以使用reduceObject.values

来缩短版本

let a = [{
    "text": "hello world",
    "startPos": 0,
    "endPos": 12,
    "value": "hello world",
    "entity": "Greeting"
  },
  {
    "text": "hello world",
    "startPos": 0,
    "endPos": 6,
    "value": "hello",
    "entity": "Greeting"
  }
];

let result = Object.values(a.reduce((c, v) => {
  c[v.text] = c[v.text] || {text: v.text,entities: []};
  c[v.text].entities.push(v);
  return c;
}, {}));

console.log(result);

没有text属性

let a = [{
    "text": "hello world",
    "startPos": 0,
    "endPos": 12,
    "value": "hello world",
    "entity": "Greeting"
  },
  {
    "text": "hello world",
    "startPos": 0,
    "endPos": 6,
    "value": "hello",
    "entity": "Greeting"
  }
];

let result = Object.values(a.reduce((c, v) => {
  let {text: _,...o} = v;
  c[v.text] = c[v.text] || {text: v.text,entities: []};
  c[v.text].entities.push(o);
  return c;
}, {}));

console.log(result);

答案 2 :(得分:0)

您可以为权限添加包含文本和数组的新对象。

此解决方案采用一个被破坏的对象并使用键构建新对象。

var a = [{ text: "hello world", startPos: 0, endPos: 12, value: "hello world", entity: "Greeting" }, { text: "hello world", startPos: 0, endPos: 6, value: "hello", entity: "Greeting" }],
    result = a.reduce((acc, { text, startPos, endPos, entity, value }) => {
        var found = acc.find(a => a.text === text),
            subEntity = { startPos, endPos, entity, value };

        if (found) {
            found.entities.push(subEntity);
        } else {
            acc.push({ text, entities: [subEntity] });
        }
        return acc;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

rest parameters ...属性destructuringBABEL

var a = [{ text: "hello world", startPos: 0, endPos: 12, value: "hello world", entity: "Greeting" }, { text: "hello world", startPos: 0, endPos: 6, value: "hello", entity: "Greeting" }],
    result = a.reduce((acc, { text, ...subEntity }) => {
        var found = acc.find(a => a.text === text);

        if (found) {
            found.entities.push(subEntity);
        } else {
            acc.push({ text, entities: [subEntity] });
        }
        return acc;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }