2017-12-18 13 views
1

EDITJavascriptデータを新しい配列にマッサージ

だから私はもう少し詳しく調べるべきだと思います。私は現在HighCharts JSで働いています。 highchartsに示されるデータのために、私は、最終的なデータを持っている必要があり、以下のように:

[ 
    { 
    name: 'Performing', 
    data: [1941404, 1028717, 697370, 0, 0, 0] 
    }, 
    { 
    name: 'Non performing', 
    data: [0, 0, 0, 1759908, 890857, 280235] 
    }, 
    { 
    name: 'Substandard', 
    data: [0, 0, 863825, 0, 0, 0] 
    }, 
    { 
    name: 'Written-off', 
    data: [0, 0, 0, 0, 0, 77146] 
    } 
] 

を「データ」は、グラフのx軸に移入6つのオブジェクトの配列です。

しかし、私はそれが元のコードのように終わるので、後者のコードをフィルタリングする必要のMongoDB

[ 
    { 
    "_id": { 
     "data": "90 - 180", 
     "status": "Non Performing" 
    }, 
    "value": 1759908 
    }, 
    { 
    "_id": { 
     "data": "360", 
     "status": "Written-off" 
    }, 
    "value": 77146 
    }, 
    { 
    "_id": { 
     "data": "360", 
     "status": "Non Performing" 
    }, 
    "value": 280235 
    }, 
    { 
    "_id": { 
     "data": "30 - 90", 
     "status": "Substandard" 
    }, 
    "value": 863825 
    }, 
    { 
    "_id": { 
     "data": "30 - 90", 
     "status": "Performing" 
    }, 
    "value": 697370 
    }, 
    { 
    "_id": { 
     "data": "180 - 360", 
     "status": "Non Performing" 
    }, 
    "value": 890857 
    }, 
    { 
    "_id": { 
     "data": "0 - 30", 
     "status": "Performing" 
    }, 
    "value": 1028717 
    }, 
    { 
    "_id": { 
     "data": "0", 
     "status": "Performing" 
    }, 
    "value": 1941404 
    } 
] 

を介して供給されている以下のデータを有しています。データ配列ではHighchartsのxAxis全体が確実に格納されるように6つのオブジェクトを作成することが重要です。したがって、データが提供されていないゼロが多数表示されます。

私は本当にこれが物事をクリアすることを願っています。助けを借りているすべての人にありがとう。オフセットからあまりにも曖昧であることをお詫び申し上げます。

QUICK NOTE 次のようにデータ配列の順序は次のとおりです。 0、0-30、30-90、90-180、180-360、360

+3

を作成し、あなたは、あなたのコードをしてください投稿することができますか? –

+0

出発点。 https://stackoverflow.com/questions/14446511/what-is-the-most-efficient-method-to-groupby-on-a-javascript-array-of-objects – Aaron

+1

「データ」はどこから来たのか説明できますか?結果として得られるオブジェクトに格納されます。 –

答えて

0

使用the reduce methodだけを指定することを忘れないでください最初のオブジェクト

newData = yourData.reduce(function(element, accumulator){ 
    if (accumulator already has element with name property equalling to element.status) { 
     // push value to existing array 
    } else { 
     // add new element 
    } 
}, {}); // second argument is just an empty object 
2

そこに.reduce.mapメソッドを使用します。 .reduceメソッドを使用してデータを結合し、必要な処理を行い、.mapメソッドを使用して配列に戻すことができます。

以下を参照してください。

const data = [ 
    { 
    "_id": { "data": "90 - 180", "status": "Non Performing" }, "value": 1759908 
    }, 
    { 
    "_id": { "data": "360", "status": "Written-off" }, "value": 77146 
    }, 
    { 
    "_id": { "data": "360", "status": "Non Performing" }, "value": 280235 
    }, 
    { 
    "_id": { "data": "30 - 90", "status": "Substandard" }, "value": 863825 
    }, 
    { 
    "_id": { "data": "30 - 90", "status": "Performing" }, "value": 697370 
    }, 
    { 
    "_id": { "data": "180 - 360", "status": "Non Performing" }, "value": 890857 
    }, 
    { 
    "_id": { "data": "0 - 30", "status": "Performing" }, "value": 1028717 
    }, 
    { 
    "_id": { "data": "0", "status": "Performing" }, "value": 1941404 
    } 
] 

const reducedMap = data.reduce((reducedMap, entry) => { 
    if(!reducedMap[entry._id.status]) reducedMap[entry._id.status] = []; 
    reducedMap[entry._id.status].push(entry.value); 
    return reducedMap; 
}, {}); 

const reducedArray = Object.keys(reducedMap).map(key => ({ 
    name: key, 
    data: reducedMap[key] 
})) 

EDIT

だからあなたのコメントや他の回答を読んだ後、私はあなたが(コメントブロックをお読みください必要なものだけを取得、この解決策を考え出しましたそれを理解するため):

// Define How the data is structured 
const orderIdx = ["0", "0 - 30", "30 - 90", "90 - 180", "180 - 360", "360"]; 
const allStatuses = ["Performing", "Non Performing", "Substandard" , "Written-off"]; 

// Construct the mapping 
const mappedIdx = orderIdx.reduce((m, key)=> { return { ...m, [key]: 0 } }, {}) 
    // mappedIdx = { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 } 
const mappedInput = allStatuses.reduce((m, name) => { 
    return {...m, [name]: Object.assign({},mappedIdx) }; 
}, {}) 
    // mappedInput = { 
    // "Performing": { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 }, 
    // "Non Performing": { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 }, 
    // "Substandard" : { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 }, 
    // "Written-off": { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 }, 
    // } 

// Loop on data 
data.forEach(row => { 
    mappedInput[row._id.status][row._id.data] = row.value 
}) 

const reducedArray = Object.keys(mappedInput).map(key => ({ 
    name: key, 
    data: Object.keys(mappedInput[key]).map(dataKey => mappedInput[key][dataKey]) 
})) 

// reducedArray = [ 
// { 
//  name: 'Performing', 
//  data: [1941404, 1028717, 697370, 0, 0, 0] 
// }, 
// { 
//  name: 'Non performing', 
//  data: [0, 0, 0, 1759908, 890857, 280235] 
// }, 
// { 
//  name: 'Substandard', 
//  data: [0, 0, 863825, 0, 0, 0] 
// }, 
// { 
//  name: 'Written-off', 
//  data: [0, 0, 0, 0, 0, 77146] 
// } 
// ] 

また、短い関数にこれを簡素化することができます:あなたはそれが非常に明確ではないとして、ちょうど彼らがどうあるべきかのそれをeyeballingからorderIdxallStatusesをparametizeする必要があります

function summarizeData(data, orderIdx, allStatuses){ 
    const mappedIdx = orderIdx.reduce((m, key)=> { return { ...m, [key]: 0 } }, {}) 
    const mappedInput = allStatuses.reduce((m, name) => { 
     return {...m, [name]: Object.assign({},mappedIdx) }; 
    }, {}) 

    data.forEach(row => { 
     mappedInput[row._id.status][row._id.data] = row.value 
    }) 

    return Object.keys(mappedInput).map(key => ({ 
     name: key, 
     data: Object.keys(mappedInput[key]).map(dataKey => mappedInput[key][dataKey]) 
    })) 
} 
summarizeData(data, ["0", "0 - 30", "30 - 90", "90 - 180", "180 - 360", "360"], ["Performing", "Non Performing", "Substandard" , "Written-off"]) 

注意。また、これらが実際に唯一の値であることを検証するプロセスを必ず入れてください。

+0

これを拡張するために、もう少しコメントを追加しました。 – asosnovsky

+1

@David Thomas、私は非常に高い評判を持つユーザーから同様の答えを見るが、downvotesと説明の要求はない。だから、詳しい説明のために(常に)尋ねなければ、ユーザーがそのような高い評価を得ていないときになぜそれをするのか? ;)P.S.この答えはほぼ正しいですが、出力を微調整する必要があります。 – sinisake

+2

@sinisake:私は個人的には、自分の評判よりも高い評判を持つ人が書いた回答に説明を求めるコメントを残しました。他の人がそうすることを選ぶかどうかは、まったくそれらに左右されます。しかし、このサイトの私の解釈は、それが与えられた言語や使用の複雑さを(まだ完全に)理解していない人たちのための教材です。だから、私は説明なしでコードをポストダウンし、コメントで説明を要求する。適切な - 私の個人的な定義 - コードの説明が答えに追加されれば、私は下方投票を取り下げ、代わりに上方投票を取りやめる。 –

-1

あなたはこのようにそれを行うことができます。

var originalArray = [ 
    { 
    "_id": { 
     "data": "90 - 180", 
     "status": "Non Performing" 
    }, 
    "value": 1759908 
    }, 
    { 
    "_id": { 
     "data": "360", 
     "status": "Written-off" 
    }, 
    "value": 77146 
    }, 
    { 
    "_id": { 
     "data": "360", 
     "status": "Non Performing" 
    }, 
    "value": 280235 
    }, 
    { 
    "_id": { 
     "data": "30 - 90", 
     "status": "Substandard" 
    }, 
    "value": 863825 
    }, 
    { 
    "_id": { 
     "data": "30 - 90", 
     "status": "Performing" 
    }, 
    "value": 697370 
    }, 
    { 
    "_id": { 
     "data": "180 - 360", 
     "status": "Non Performing" 
    }, 
    "value": 890857 
    }, 
    { 
    "_id": { 
     "data": "0 - 30", 
     "status": "Performing" 
    }, 
    "value": 1028717 
    }, 
    { 
    "_id": { 
     "data": "0", 
     "status": "Performing" 
    }, 
    "value": 1941404 
    } 
]; 

var newArray = [ 
    { 
     'name': 'Performing', 
    'data': [] 
    }, 
    { 
     'name': 'Non Performing', 
    'data': [] 
    }, 
    { 
     'name': 'Substandard', 
    'data': [] 
    }, 
    { 
     'name': 'Written-off', 
    'data': [] 
    } 
]; 

for (var x = 0; x < originalArray.length; x++) { 
    if (originalArray[x]._id.status === 'Performing') { 
    for (var y = 0; y < newArray.length; y++) { 
     if (newArray[y].name === 'Performing') { 
     newArray[y].data.push(originalArray[x]._id.data) 
     } 
    } 
    } else if (originalArray[x]._id.status === 'Non Performing') { 
    for (var y = 0; y < newArray.length; y++) { 
     if (newArray[y].name === 'Non Performing') { 
     newArray[y].data.push(originalArray[x]._id.data) 
     } 
    } 
    } else if (originalArray[x]._id.status === 'Substandard') { 
    for (var y = 0; y < newArray.length; y++) { 
     if (newArray[y].name === 'Substandard') { 
     newArray[y].data.push(originalArray[x]._id.data) 
     } 
    } 
    } else if (originalArray[x]._id.status === 'Written-off') { 
    for (var y = 0; y < newArray.length; y++) { 
     if (newArray[y].name === 'Written-off') { 
     newArray[y].data.push(originalArray[x]._id.data) 
     } 
    } 
    } 
} 

console.log(newArray); 

の作業例:一般的にhttps://jsfiddle.net/extro3tw/

+0

OPや他の誰かが、あなたが何をしているのかを説明する時間を取らずに、なぜ、あなたのコードから学ぶことが期待ですか? –

+0

なぜスタックスニペットの代わりにjsfiddleをデモンストレーションに使用するのですか? – Barmar

0

あなたはまだそれが受け入れオブジェクトとリターンについての話をしながら、あなたのコードは、できるだけ簡潔にしたいです。以下のようなものは、受け入れられたフォーマットされていないオブジェクトを記述し、それに対して実行される変換を記述し、関数が返すオブジェクトを暗黙に記述します。

function generateFormattedArray(unformattedDataArray) { 
    const flattenedDataArray = unformattedDataArray.forEach((obj) => { status: obj['_id'].status, value: obj.value }); 
    return [ 
    { 
     name: 'Performing', 
     data: flattenedDataArray.filter((obj) => obj.status === 'Performing').forEach((obj) => obj.value), 
    }, 
    { 
     name: 'Non performing', 
     data: flattenedDataArray.filter((obj) => obj.status === 'Non performing').forEach((obj) => obj.value), 
    }, 
    { 
     name: 'Substandard', 
     data: flattenedDataArray.filter((obj) => obj.status === 'Substandard').forEach((obj) => obj.value), 
    }, 
    { 
     name: 'Written-off', 
     data: flattenedDataArray.filter((obj) => obj.status === 'Written-off').forEach((obj) => obj.value), 
    }, 
    ]; 
} 

このネストされたフォーマットのための具体的なユースケースがない限り、正直に言うが...私はおそらくかなりflattenedDataArrayに働くだろう行に2

関連する問題