按键前缀过滤JavaScript对象并通过reduce构建新对象

3

我正在从一个大型数据导出API中获取数据,并需要更好地过滤数据。目前,以下是我所看到的示例。

{
  AA-Short: "information",
  AA-Long: "more information",
  AA-Extra: "even more information",
  BB-Short: "information",
  BB-Long: "more information",
  BB-Extra: "even more information",
} 

我正在尝试制作这个:

{
  AA: {
     AA-Short: "information",
     AA-Long: "more information",
     AA-Extra: "even more information"
  },
  BB: {
     BB-Short: "information",
     BB-Long: "more information",
     BB-Extra: "even more information"
  }
} 

1
你能发一下你尝试过的内容吗? - jonatjano
@brk只要你将它放在引号之间,它就是有效的。 - jonatjano
嗨!请参观一下[导览](您将获得徽章!)并仔细阅读[帮助文档],尤其是如何提出一个好问题? 在这里,你最好先做些调查研究,搜索相关主题在 SO 上,并尝试一下。这只是简单地循环属性、捕获前缀和创建对象的问题。如果你遇到困难并且无法在进一步调查和搜索后解决问题,请发布一个你所尝试的 [mcve] 并明确说明你卡在哪里。大家都会乐意帮助你的。 - T.J. Crowder
6个回答

1
这是一个编程相关的示例,下面是保留 HTML 标签的翻译:

这里是一个实现的例子:

const data = {
  "AA-Short": "information",
  "AA-Long": "more information",
  "AA-Extra": "even more information",
  "BB-Short": "information",
  "BB-Long": "more information",
  "BB-Extra": "even more information",
};
const dataKeys = Object.keys(data);
const groupedData = dataKeys.reduce((result, currKey) => {
  // Pull out the group name from the key
  const group = currKey.split('-')[0];
  // Check if the group exists, if not, create it
  const hasGroup = result[group] !== undefined;
  if (!hasGroup)
    result[group] = {};
  // Add the current entry to the result
  result[group][currKey] = data[currKey];
  return result;
}, {});

这就是我差一点就完成的东西。我缺少的是hasGroup部分。谢谢! - WhosDustin

1
使用for..in迭代对象,然后使用substring获取前两个字符。创建一个新对象,并检查是否存在一个与前两个字符匹配的键名,然后添加值。

let x = {
  "AA-Short": "information",
  "AA-Long": "more information",
  "AA-Extra": "even more information",
  "BB-Short": "information",
  "BB-Long": "more information",
  "BB-Extra": "even more information"
}

let newObject = {}
for (let key in x) {
  let firstChars = key.substring(0, 2);
  if (!newObject.hasOwnProperty(firstChars)) {
    newObject[firstChars] = {};
    newObject[firstChars][key] = x[key]
  } else {
    newObject[firstChars][key] = x[key]
  }
}
console.log(newObject)


0

这里可以做什么

let data = {
  "AA-Short": "information",
  "AA-Long": "more information",
  "AA-Extra": "even more information",
  "BB-Short": "information",
  "BB-Long": "more information",
  "BB-Extra": "even more information",
}


for (let i in data) {
  // get part of the path
  path = i.split("-") // e.g. ["AA", "Short"]

  // remove the last
  path.pop()

  // go into the tree creating a new node for each step if needed
  subdata = data
  for (let j of path) {
    if (typeof subdata[j] === "undefined") {
      subdata[j] = {}
    }
    subdata = subdata[j]
  }

  // put the datas when reaching the end of the path
  subdata[i] = data[i]
  // delete the original data
  delete data[i]
}

console.log(data)

如果你遇到类似的情况,请使用这个。

"AA-Short": "information",
"AA-Short-Short": "info"

并且所有的值都是字符串

let data = {
    "AA-Short": "information",
    "AA-Short-Short": "info",
    "BB-Short": "information",
    "BB-Short-Short": "info"
}


for (let i in data) {
  // get part of the path
  path = i.split("-") // e.g. ["AA", "Short"]

  // remove the last
  path.pop()

  // go into the tree creating a new node for each step if needed
  subdata = data
  for (let j of path) {
    if (typeof subdata[j] === "undefined") {
      subdata[j] = {}
    }
    subdata = subdata[j]
  }

  // put the datas when reaching the end of the path
  subdata[i] = new String(data[i])
  // delete the original data
  delete data[i]
}

console.log(data)

输出可能会让它看起来像是破坏了一切,但实际上这是正确的,因为String是一个字符数组。


0
你可以使用 for..in 循环,在循环内部检查键,通过分割 - 并创建相应的对象。
let result = {};

for (v in data) {
  let key = v.split("-")[0];
  if (!result.hasOwnProperty(key))
    result[key] = {};
  result[key][v] = data[v];
}

演示:

var data = {
  "AA-Short": "information",
  "AA-Long": "more information",
  "AA-Extra": "even more information",
  "BB-Short": "information",
  "BB-Long": "more information",
  "BB-Extra": "even more information",
};

let result = {};

for (v in data) {
  let key = v.split("-")[0];
  if (!result.hasOwnProperty(key))
    result[key] = {};
  result[key][v] = data[v];
}

console.log(result);


如果存在一个CC键,会怎么样? - executable
@executable 我修改了答案,使其更具动态性和简洁性。 - cнŝdk

0

同一种Map-Reduce算法的另一个变体

const start = {
  "AA-Short": "information",
  "AA-Long": "more information",
  "AA-Extra": "even more information",
  "BB-Short": "information",
  "BB-Long": "more information",
    "BB-Extra": "even more information",
};

const aa = new Set(Object.keys(start).filter(k => k.split("-")[0] === "AA"));

const bb = new Set(Object.keys(start).filter(k => k.split("-")[0] === "BB"));

const rAA = {};
const rBB = {};

const result = Object.entries(start)
  .reduce((result, [k, v]) => {
    if (aa.has(k)) {
      return {
        ...result,
        AA: {
          ...result.AA,
          [k]: v
        }
      };
    }
    if (bb.has(k)) {
      return {
        ...result,
        BB: {
          ...result.BB,
          [k]: v
        }
      };
    }
    throw new Error("Unexpected key");

  }, {AA: {}, BB: {}});

console.log(result);

0
获取对象的键并将它们按照以下方式合并到新对象中:
let result = Object.keys(obj).reduce((acc, key) => {    // for each key in obj
  let newKey = key.split("-")[0];                       // get the sub key
  if(acc[newKey]) {                                     // if there is already an object for this sub key in the accumulator
    acc[newKey][key] = obj[key];                        // add the current object to it
  }
  else {                                                // otherwise
    acc[newKey] = { [key]: obj[key] };                  // create a new object for this sub key that initially contains the current object
  }
  return acc;
}, {});

例子:

let obj = { "AA-Short": "information", "AA-Long": "more information", "AA-Extra": "even more information", "BB-Short": "information", "BB-Long": "more information", "BB-Extra": "even more information" };

let result = Object.keys(obj).reduce((acc, key) => {
  let newKey = key.split("-")[0];
  if(acc[newKey]) {
    acc[newKey][key] = obj[key];
  }
  else {
    acc[newKey] = { [key]: obj[key] };
  }
  return acc;
}, {});

console.log(result)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接