#javascript #json
Вопрос:
У меня есть json
input_lookup = [{"keyprefixname": "fruit","resultkey":"sweet" },
{"keyprefixname": "rate","resultkey":"ratex" }]
input = {
'fruit_a': "red apple"
'fruit_b': "green apple"
'rate_a': "10$"
'rate_b': "20$"
'vegetable_a': "spinach"
'vegetable_b': "carrot"
}
Входной json содержит некоторые префиксы, перечисленные в поиске, и нам нужно объединить перечисленные, образуя новые пары ключей json с комбинированным значением
ожидаемый результат составляет
result_output = {
'sweet': "red apple,green apple"
'ratex': "10$,20$"
'vegetable_a': "spinach" // not to combine this since it wont exist in lookup
'vegetable_b': "carrot"
}
Я пробовал с
result_output = {}
for(key in input_lookup){
if(key.indexOf(input_lookup) > -1)
key = key input_lookup[key]
}
Ответ №1:
Есть несколько способов сделать это. Вот редуктор, используемый Array.find
для сравнения значений поиска со значением из входных данных:
const lookup = [
{prefix: "fruit", key: "sweet" },
{prefix: "rate", key: "ratex" },
];
const input = {
fruit_a: "red apple",
fruit_b: "green apple",
rate_a: "10$",
rate_b: "20$",
vegetable_a: "spinach",
vegetable_b: "carrot",
};
const reducedWithArrayOfValues = Object.entries(input)
.reduce( (acc, [key, value]) => {
const nwKey = lookup.find(v => key.startsWith(v.prefix));
return nwKey
? { ...acc, [nwKey.key]: (acc[nwKey.key] ||[]).concat(value) }
: { ...acc, [key]: value };
}, {}
);
const reducedWithStringValues = Object.entries(input)
.reduce( (acc, [key, value]) => {
const nwKey = lookup.find(v => key.startsWith(v.prefix));
return nwKey
? { ...acc, [nwKey.key]: `${acc[nwKey.key] ? `${
acc[nwKey.key]}#` : ""}${value}` }
: { ...acc, [key]: value };
}, {}
);
document.querySelector(`pre`).textContent =
JSON.stringify(reducedWithStringValues, null, 2);
document.querySelector(`pre`).textContent = `n---n${
JSON.stringify(reducedWithArrayOfValues, null, 2)}`;
<pre></pre>
Комментарии:
1. Это самый многообещающий ответ. Могу ли я узнать, к какой строке я могу присоединиться с помощью разделителя? вместо красного яблока-зеленое яблоко. Я хотел бы иметь красное яблоко#зеленое яблоко
2. Привет @user16731842, добавлен второй редуктор
reducedWithStringValues
, доставляющий нужные строки
Ответ №2:
вот, пожалуйста
function getAggregateKey(key, value) {
const result = input_lookup.find((item) => key.includes(item.keyprefixname));
if (result) {
return result["resultkey"];
}
return key;
}
const arrayObject = Object.entries(input).reduce((acc, cur) => {
const aggKey = getAggregateKey(cur[0]);
if (!(aggKey in acc)) {
acc[aggKey] = [];
}
acc[aggKey].push(cur[1])
return acc;
}, {});
const result = Object.entries(arrayObject).reduce((acc, cur) => {
acc[cur[0]] = cur[1].join(',');
return acc;
}, {});
console.log(result);
Ответ №3:
let input_lookup = [{
"keyprefixname": "fruit",
"resultkey": "sweet"
}, {
"keyprefixname": "rate",
"resultkey": "ratex"
}];
let input = {
'fruit_a': "red apple",
'fruit_b': "green apple",
'rate_a': "10$",
'rate_b': "20$",
'vegetable_a': "spinach",
'vegetable_b': "carrot"
};
// first we need a good lookup object the default is an array
// we made fruit > sweet and rate > ratex
// this is help later in the code
var good_lookup = {};
for(let i = 0; i < input_lookup.length ; i ){
let good_key = input_lookup[i]['keyprefixname'];
let good_val = input_lookup[i]['resultkey'];
good_lookup[good_key] = good_val;
}
let result_output = {};
for(let key in input ){
let to_lookup = key.split('_');
let to_lookup_key = to_lookup[0];//fruit, rate
var to_aggregate = good_lookup[to_lookup_key];
if(to_aggregate){
if(result_output[to_aggregate]){
result_output[to_aggregate] = result_output[to_aggregate] ", " input[key];
} else {
result_output[to_aggregate] = input[key];
}
} else {
result_output[key] = input[key];
}
}
console.log(result_output);
вот скрипка для кода https://jsfiddle.net/z8usmgja/1/