首页 > 解决方案 > 计算多个json输入js

问题描述

我得到这样的输入:

input 1:

{

"name": "Ben",
"description": "Ben",
"attributes": [
    {
    "type": "Background",
    "value": "Default"
    },
    {
    "type": "Hair-color",
    "value": "Brown"
    }
]
}

input 2

{

"name": "Ice",
"description": "Ice",
"attributes": [
    {
    "type": "Background",
    "value": "Green"
    },
    {
    "type": "Hair-color",
    "value": "White"
    }
]
}

input 3

{

"name": "Itay",
"description": "Itay",
"attributes": [
    {
    "type": "Background",
    "value": "Default"
    },
    {
    "type": "Hair-color",
    "value": "Brown"
    }
]
}

我想做的是计算每种背景和每种头发颜色出现的数量。(这些是示例示例,实际上有更多类型和不同的值)

假设在这些示例中,我们有 2 个默认具有背景的对象,那么我想要这样计数:

export interface TraitCount {
    value: string,
    count: number
}

export interface CountOfEachAttribute {
    trait_type: string,
    trait_count: traitCount[] | null,
    total_variations: number
}

我想要最有效的代码,因为代码还有其他方面,此外它将在 5-10k 查询上运行,而不仅仅是三个,所以也需要在好的时候运行:D(这类似于我用 python 完成的另一个问题,但现在我在 js 中也需要它)

自动取款机是这样的:

(除了更大的代码,请记住这一点)

    setInitalCountOfAllAttribute( state, { payload }: PayloadAction<CountOfEachAttribute[] | null> ) {
      if (payload === null) {
        state.countOfAllAttribute = null;
      } else {
        state.countOfAllAttribute = payload;
      }
    },

    setCountOfAllAttribute(state, { payload }: PayloadAction<Attribute>) {

      if (state.countOfAllAttribute !== null) {
        state.countOfAllAttribute.map(
          (countOfEachAttribute: CountOfEachAttribute) => {

            // Find the trait type
            if (countOfEachAttribute.trait_type === payload.trait_type) {

              // initiate the trait count array to store all the trait values and add first trait value
              if (countOfEachAttribute.trait_count === null) {
                const new_trait_count = { value: payload.value, count: 1 };
                countOfEachAttribute.trait_count = [new_trait_count];
                countOfEachAttribute.total_variations++;
              } 

              // Trait array already existed. 
              else {

                // Check if value already present or not
                const checkValue = (obj: any) => obj.value === String(payload.value);
                const isPresent = countOfEachAttribute.trait_count.some(checkValue)
                const isPresent2 = countOfEachAttribute.trait_count.find((elem: any) => elem.value === String(payload.value))

                // Value matched, increase its count by one
                  if (isPresent2) {
                  countOfEachAttribute.trait_count &&
                    countOfEachAttribute.trait_count.map((trait) => {
                      if (trait.value === payload.value) {
                        trait.count++;
                      }
                    });
                } 

                // Value doesn't match, add a new entry and increase the count of variations by one
                else {
                  const new_trait_count = { value: payload.value, count: 1 };
                  countOfEachAttribute.trait_count = [
                    ...countOfEachAttribute.trait_count,
                    new_trait_count,
                  ];
                  countOfEachAttribute.total_variations++;
                }
              }
            }
          }
        );
      }
    },

标签: javascriptjsontypescriptformattingcounting

解决方案


您可以合并所有数组并使用Array.reduce.

const input1 = {
  "name": "Ben",
  "description": "Ben",
  "attributes": [{
      "type": "Background",
      "value": "Default"
    },
    {
      "type": "Hair-color",
      "value": "Brown"
    }
  ]
}
const input2 = {
  "name": "Ice",
  "description": "Ice",
  "attributes": [{
      "type": "Background",
      "value": "Green"
    },
    {
      "type": "Hair-color",
      "value": "White"
    }
  ]
}
const input3 = {
  "name": "Itay",
  "description": "Itay",
  "attributes": [{
      "type": "Background",
      "value": "Default"
    },
    {
      "type": "Hair-color",
      "value": "Brown"
    }
  ]
}

const mergedInput = [input1, input2, input3];

const result = mergedInput.reduce((acc, item) => {
  
  item.attributes.forEach(attrItem => {
    const existType = acc.find(e => e.trait_type == attrItem.type);
    if (existType) {
        var existAttr = existType.trait_count.find(e => e.value == attrItem.value);
      if (existAttr) {
        existAttr.count++;
      } else {
        existType.trait_count.push({
            value: attrItem.value,
          count: 1
        });
        existType.total_variations++;
      }
    } else {
        acc.push({
        trait_type: attrItem.type,
        trait_count: [{
            value: attrItem.value,
          count: 1
        }],
        total_variations: 1
      })
    }
  });
  return acc;
}, []);

console.log(result);


推荐阅读