0

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

arrObj = [{
  id: 1
  data: {
    info: {
      name: 'jhon'
    }
  }
},{
  id: 1
  data: {
    info: {
      name: 'jane'
    }
  }
},{
  id: 1
  data: {
    info: {
      name: 'jhon'
    }
  }
}]

我需要获得不同值的出现摘要,如下所示:

{ jane: 1, jhon: 2 }

最大的问题是我需要动态传递嵌套的道具:

getSummary('data.info.name',obj) //--> { jane: 1, jhon: 2 }

有任何想法吗?

4

3 回答 3

0

您可以使用以下代码,这只是提示。如果某些输入没有正确的嵌套键,则需要进行错误处理。

let arrObj = [{
  id: 1,
  data: {
    info: {
      name: 'jhon'
    }
  }
},{
  id: 1,
  data: {
    info: {
      name: 'jane'
    }
  }
},{
  id: 1,
  data: {
    info: {
      name: 'jhon'
    }
  }
}]

const getSummary = (dynamicKeys,obj) => {
  const list = dynamicKeys.split('.');
  const op = {};
  for (let i = 0; i < obj.length; i++) {
    let n = 1, key = obj[i][list[0]];
    while (list.length > n) {
      key = key[list[n]];
      n++;
    }
    op[key] = op[key] ? op[key] + 1 : 1;
  }
  return op;
}

const test = getSummary('data.info.name', arrObj);
console.log(test)

于 2020-07-17T08:05:30.073 回答
0

可能的解决方案如下。这里首先从arrayObj的每个元素中找到给定的prop。如果查找不成功,则跳过该元素并移至下一个。查找成功后,如果在 summary 中不存在查找值,则将其附加到 summary 或增加现有值。您可以根据需要更改代码。

const arrObj = [{
  id: 1,
  data: {
    info: {
      name: 'jhon'
    }
  }
}, {
  id: 1,
  data: {
    info: {
      name: 'jane'
    }
  }
}, {
  id: 1,
  data: {
    info: {
      name: 'jhon'
    }
  }
}];


const getSummary = (prop, arr) => {
  const keys = prop.split('.');
  const findPropValue = (elem) =>
    keys.reduce((val, key, index) => {
      if (index === 0) return elem[key];
      return (val && val[key]) || val
    }, null);
  return arr.reduce((sum, curr) => {
    const key = findPropValue(curr);
    if (!key) return sum;
    sum[key] = (sum[key] && sum[key] + 1) || 1;
    return sum;
  }, {});
};


console.log(getSummary('data.info.name', arrObj));

于 2020-07-17T08:54:34.353 回答
0

使用forEach. 对于每个对象,访问该值并使用键作为值(例如 jane)构建一个res对象,然后聚合对象值。[通过split路径访问值,访问嵌套使用的对象reduce

const getSummary = (path, items) => {
  const paths = path.split(".");
  const res = {};
  items.forEach((item) => {
    const value = paths.reduce((acc, cur) => acc[cur], item);
    res[value] = (res[value] ?? 0) + 1;
  });
  return res;
};

arrObj = [
  {
    id: 1,
    data: {
      info: {
        name: "jhon",
      },
    },
  },
  {
    id: 1,
    data: {
      info: {
        name: "jane",
      },
    },
  },
  {
    id: 1,
    data: {
      info: {
        name: "jhon",
      },
    },
  },
];

const output = getSummary("data.info.name", arrObj);
console.log(output);

于 2020-07-17T09:39:50.883 回答