중첩된 JavaScript 개체를 평탄화/평탄화 해제하는 가장 빠른 방법
복잡한 자바스크립트 오브젝트를 평평하게 하거나 평평하게 하지 않기 위해 코드를 조합했습니다.동작하지만, 조금 느립니다('긴 스크립트' 경고 트리거).
평탄한 이름의 경우 구분 기호로 "."를 사용하고 배열의 경우 [INDEX]를 사용합니다.
예:
un-flattened | flattened
---------------------------
{foo:{bar:false}} => {"foo.bar":false}
{a:[{b:["c","d"]}]} => {"a[0].b[0]":"c","a[0].b[1]":"d"}
[1,[2,[3,4],5],6] => {"[0]":1,"[1].[0]":2,"[1].[1].[0]":3,"[1].[1].[1]":4,"[1].[2]":5,"[2]":6}
사용 사례를 시뮬레이션하는 벤치마크를 작성했습니다.http://jsfiddle.net/WSzec/
- 중첩된 개체 가져오기
- 평평하게 하다
- 훑어보고 평탄한 상태에서 수정할 수 있습니다.
- 원래 네스트된 포맷으로 되돌려서 출하합니다.
더 빠른 코드를 원합니다.명확히 하기 위해 IE 9+, FF 24+ 및 Chrome 29+에서는 JSFiddle 벤치마크를 완료하는 코드(http://jsfiddle.net/WSzec/)가 훨씬 더 빠릅니다(~20% 이상이면 좋습니다).
다음은 관련 JavaScript 코드입니다.현재 가장 빠른 속도: http://jsfiddle.net/WSzec/6/
var unflatten = function(data) {
"use strict";
if (Object(data) !== data || Array.isArray(data))
return data;
var result = {}, cur, prop, idx, last, temp;
for(var p in data) {
cur = result, prop = "", last = 0;
do {
idx = p.indexOf(".", last);
temp = p.substring(last, idx !== -1 ? idx : undefined);
cur = cur[prop] || (cur[prop] = (!isNaN(parseInt(temp)) ? [] : {}));
prop = temp;
last = idx + 1;
} while(idx >= 0);
cur[prop] = data[p];
}
return result[""];
}
var flatten = function(data) {
var result = {};
function recurse (cur, prop) {
if (Object(cur) !== cur) {
result[prop] = cur;
} else if (Array.isArray(cur)) {
for(var i=0, l=cur.length; i<l; i++)
recurse(cur[i], prop ? prop+"."+i : ""+i);
if (l == 0)
result[prop] = [];
} else {
var isEmpty = true;
for (var p in cur) {
isEmpty = false;
recurse(cur[p], prop ? prop+"."+p : p);
}
if (isEmpty)
result[prop] = {};
}
}
recurse(data, "");
return result;
}
편집 1 위의 내용을 현재 가장 빠른 @Bergi의 구현으로 변경.한편, 「regex.exec」 대신에 「.indexOf」를 사용하는 것이 FF에서는 약 20% 고속이지만, Chrome에서는 약 20% 저속입니다.따라서 regex가 더 심플하기 때문에 regex를 계속 사용합니다(여기에서는 regex http://jsfiddle.net/WSzec/2/)를 대체하기 위해 indexOf를 사용하려고 합니다.
편집 2 @Bergi의 아이디어에 따라 나는 더 빠른 비정규 버전(FF에서는 3배, Chrome에서는 최대 10%)을 만들 수 있었습니다.http://jsfiddle.net/WSzec/6/ 이 (현재의) 실장에서는, 키명의 룰은 간단하게, 키는 정수로 개시할 수 없고, 마침표를 포함할 수 없습니다.
예:
- {"foo":{"bar":[0]}} => {"foo.bar.0":0}
편집 3 @Aadit 추가(String.split이 아닌) MSHA의 인라인 경로 구문 분석 접근 방식을 통해 플랫텐 해제 성능이 향상되었습니다.전반적인 실적 향상에 매우 만족합니다.
최신 jsfiddle 및 jsperf:
http://jsperf.com/flatten-un-flatten/4
다음은 훨씬 짧은 구현입니다.
Object.unflatten = function(data) {
"use strict";
if (Object(data) !== data || Array.isArray(data))
return data;
var regex = /\.?([^.\[\]]+)|\[(\d+)\]/g,
resultholder = {};
for (var p in data) {
var cur = resultholder,
prop = "",
m;
while (m = regex.exec(p)) {
cur = cur[prop] || (cur[prop] = (m[2] ? [] : {}));
prop = m[2] || m[1];
}
cur[prop] = data[p];
}
return resultholder[""] || resultholder;
};
flatten
별로 변하지 않았습니다(그리고 정말 필요한지는 잘 모르겠습니다).isEmpty
케이스) :
Object.flatten = function(data) {
var result = {};
function recurse (cur, prop) {
if (Object(cur) !== cur) {
result[prop] = cur;
} else if (Array.isArray(cur)) {
for(var i=0, l=cur.length; i<l; i++)
recurse(cur[i], prop + "[" + i + "]");
if (l == 0)
result[prop] = [];
} else {
var isEmpty = true;
for (var p in cur) {
isEmpty = false;
recurse(cur[p], prop ? prop+"."+p : p);
}
if (isEmpty && prop)
result[prop] = {};
}
}
recurse(data, "");
return result;
}
이 두 가지를 합치면 벤치마크 실행 시간이 절반으로 단축됩니다(Opera 12.16: ~900ms, Chrome 29: ~1600ms 대신 ~800ms).
주의: 이 솔루션과 여기에 답변된 대부분의 다른 솔루션은 속도에 중점을 두고 있으며 시제품 오염의 영향을 받기 쉬우며 신뢰할 수 없는 물체에 사용하지 마십시오.
.flatten
★★★★★★★★★★★★★★★★★」unflatten
JSON 브 j j
var flatten = (function (isArray, wrapped) {
return function (table) {
return reduce("", {}, table);
};
function reduce(path, accumulator, table) {
if (isArray(table)) {
var length = table.length;
if (length) {
var index = 0;
while (index < length) {
var property = path + "[" + index + "]", item = table[index++];
if (wrapped(item) !== item) accumulator[property] = item;
else reduce(property, accumulator, item);
}
} else accumulator[path] = table;
} else {
var empty = true;
if (path) {
for (var property in table) {
var item = table[property], property = path + "." + property, empty = false;
if (wrapped(item) !== item) accumulator[property] = item;
else reduce(property, accumulator, item);
}
} else {
for (var property in table) {
var item = table[property], empty = false;
if (wrapped(item) !== item) accumulator[property] = item;
else reduce(property, accumulator, item);
}
}
if (empty) accumulator[path] = table;
}
return accumulator;
}
}(Array.isArray, Object));
퍼포먼스:
- 현재 Opera의 솔루션보다 빠릅니다.현재 솔루션은 Opera에서 26% 느립니다.
- 파이어폭스의 현재 솔루션보다 빠릅니다.현재 솔루션은 Firefox에서 9% 느립니다.
- 현재 크롬의 솔루션보다 빠릅니다.현재의 솔루션은 크롬이 29% 느립니다.
function unflatten(table) {
var result = {};
for (var path in table) {
var cursor = result, length = path.length, property = "", index = 0;
while (index < length) {
var char = path.charAt(index);
if (char === "[") {
var start = index + 1,
end = path.indexOf("]", start),
cursor = cursor[property] = cursor[property] || [],
property = path.slice(start, end),
index = end + 1;
} else {
var cursor = cursor[property] = cursor[property] || {},
start = char === "." ? index + 1 : index,
bracket = path.indexOf("[", start),
dot = path.indexOf(".", start);
if (bracket < 0 && dot < 0) var end = index = length;
else if (bracket < 0) var end = index = dot;
else if (dot < 0) var end = index = bracket;
else var end = index = bracket < dot ? bracket : dot;
var property = path.slice(start, end);
}
}
cursor[property] = table[path];
}
return result[""];
}
퍼포먼스:
- 현재 Opera의 솔루션보다 빠릅니다.현재 솔루션은 Opera에서 5% 느립니다.
- 파이어폭스의 현재 솔루션보다 느립니다.파이어폭스에서는 솔루션 속도가 26% 느립니다.
- 현재 크롬의 솔루션보다 느립니다.내 솔루션은 크롬이 6% 느리다.
전체적으로 현재 솔루션과 동등하게, 또는 더 나은 성능을 발휘합니다.
퍼포먼스:
- 현재 Opera의 솔루션보다 빠릅니다.현재 솔루션은 Opera에서 21% 느립니다.
- 현재 Firefox 솔루션과 같은 속도입니다.
- 파이어폭스의 현재 솔루션보다 빠릅니다.현재 솔루션은 크롬이 20% 느립니다.
출력 형식:
평면 객체는 객체 특성에 점 표기법을 사용하고 배열 색인에 대괄호 표기법을 사용합니다.
{foo:{bar:false}} => {"foo.bar":false}
{a:[{b:["c","d"]}]} => {"a[0].b[0]":"c","a[0].b[1]":"d"}
[1,[2,[3,4],5],6] => {"[0]":1,"[1][0]":2,"[1][1][0]":3,"[1][1][1]":4,"[1][2]":5,"[2]":6}
내 생각에 이 형식은 도트 표기법만 사용하는 것보다 낫다.
{foo:{bar:false}} => {"foo.bar":false}
{a:[{b:["c","d"]}]} => {"a.0.b.0":"c","a.0.b.1":"d"}
[1,[2,[3,4],5],6] => {"0":1,"1.0":2,"1.1.0":3,"1.1.1":4,"1.2":5,"2":6}
장점:
- 개체를 평평하게 만드는 것이 현재 솔루션보다 빠릅니다.
- 개체의 평탄화 및 평탄화 해제 속도는 현재 솔루션과 같거나 더 빠릅니다.
- 평면 객체는 읽기 쉽도록 점 표기법과 괄호 표기법을 모두 사용합니다.
단점:
- 대부분의 경우(전부는 아니지만) 현재 솔루션보다 개체의 평탄화 해제 속도가 느립니다.
현재 JSFiddle 데모에서는 다음 값이 출력으로 제공되었습니다.
Nested : 132175 : 63
Flattened : 132175 : 564
Nested : 132175 : 54
Flattened : 132175 : 508
업데이트된 JSFiddle 데모는 다음과 같은 값을 출력으로 제공했습니다.
Nested : 132175 : 59
Flattened : 132175 : 514
Nested : 132175 : 60
Flattened : 132175 : 451
그게 무슨 뜻인지 잘 모르겠으니 jsPerf 결과를 참고하겠습니다.결국 jsPerf는 성능 벤치마킹 유틸리티입니다.JSFiddle은 아니다.
ES6 버전:
const flatten = (obj, path = '') => {
if (!(obj instanceof Object)) return {[path.replace(/\.$/g, '')]:obj};
return Object.keys(obj).reduce((output, key) => {
return obj instanceof Array ?
{...output, ...flatten(obj[key], path + '[' + key + '].')}:
{...output, ...flatten(obj[key], path + key + '.')};
}, {});
}
예:
console.log(flatten({a:[{b:["c","d"]}]}));
console.log(flatten([1,[2,[3,4],5],6]));
3년 반 후...
제 프로젝트에서는 JSON 객체를 mongoDB 도트 표기로 평탄하게 만들고 싶었고 간단한 해결책을 생각해냈습니다.
/**
* Recursively flattens a JSON object using dot notation.
*
* NOTE: input must be an object as described by JSON spec. Arbitrary
* JS objects (e.g. {a: () => 42}) may result in unexpected output.
* MOREOVER, it removes keys with empty objects/arrays as value (see
* examples bellow).
*
* @example
* // returns {a:1, 'b.0.c': 2, 'b.0.d.e': 3, 'b.1': 4}
* flatten({a: 1, b: [{c: 2, d: {e: 3}}, 4]})
* // returns {a:1, 'b.0.c': 2, 'b.0.d.e.0': true, 'b.0.d.e.1': false, 'b.0.d.e.2.f': 1}
* flatten({a: 1, b: [{c: 2, d: {e: [true, false, {f: 1}]}}]})
* // return {a: 1}
* flatten({a: 1, b: [], c: {}})
*
* @param obj item to be flattened
* @param {Array.string} [prefix=[]] chain of prefix joined with a dot and prepended to key
* @param {Object} [current={}] result of flatten during the recursion
*
* @see https://docs.mongodb.com/manual/core/document/#dot-notation
*/
function flatten (obj, prefix, current) {
prefix = prefix || []
current = current || {}
// Remember kids, null is also an object!
if (typeof (obj) === 'object' && obj !== null) {
Object.keys(obj).forEach(key => {
this.flatten(obj[key], prefix.concat(key), current)
})
} else {
current[prefix.join('.')] = obj
}
return current
}
기능 및/또는 경고
- JSON 오브젝트만 받아들입니다. 만약에
{a: () => {}}
네가 원하는 걸 얻지 못할 수도 있어! - 빈 배열 및 개체를 제거합니다. 이 ★★★★★★★★★★★★★★★★★.
{a: {}, b: []}
{}
.
이 라이브러리 사용:
npm install flat
사용방법(https://www.npmjs.com/package/flat):
평탄화:
var flatten = require('flat')
flatten({
key1: {
keyA: 'valueI'
},
key2: {
keyB: 'valueII'
},
key3: { a: { b: { c: 2 } } }
})
// {
// 'key1.keyA': 'valueI',
// 'key2.keyB': 'valueII',
// 'key3.a.b.c': 2
// }
플랫텐 해제:
var unflatten = require('flat').unflatten
unflatten({
'three.levels.deep': 42,
'three.levels': {
nested: true
}
})
// {
// three: {
// levels: {
// deep: 42,
// nested: true
// }
// }
// }
위의 답변보다 속도가 느리지만(약 1000밀리초), 흥미로운 아이디어를 가진 또 다른 접근방식이 있습니다:-)
각 속성 체인을 통해 반복하는 대신 마지막 속성을 선택하고 나머지는 룩업 테이블을 사용하여 중간 결과를 저장합니다.이 룩업 테이블은 속성 체인이 남아 있지 않고 모든 값이 연결되지 않은 속성에 있을 때까지 반복됩니다.
JSON.unflatten = function(data) {
"use strict";
if (Object(data) !== data || Array.isArray(data))
return data;
var regex = /\.?([^.\[\]]+)$|\[(\d+)\]$/,
props = Object.keys(data),
result, p;
while(p = props.shift()) {
var m = regex.exec(p),
target;
if (m.index) {
var rest = p.slice(0, m.index);
if (!(rest in data)) {
data[rest] = m[2] ? [] : {};
props.push(rest);
}
target = data[rest];
} else {
target = result || (result = (m[2] ? [] : {}));
}
target[m[2] || m[1]] = data[p];
}
return result;
};
" " " 를 하고 있습니다.data
테이블에 대한 입력 매개 변수를 입력하고 테이블에 많은 속성을 추가합니다. 비파괴 버전도 가능합니다. 영리한 사람일지도 모른다lastIndexOf
합니다.regex(regex "regex")는 regex(regex "regex")를 사용합니다.
실제 동작은 이쪽에서 확인하세요.
https://github.com/hughsk/flat 를 사용할 수 있습니다.
중첩된 Javascript 개체를 가져와서 평평하게 하거나 구분된 키로 개체의 평활을 해제합니다.
문서의 예
var flatten = require('flat')
flatten({
key1: {
keyA: 'valueI'
},
key2: {
keyB: 'valueII'
},
key3: { a: { b: { c: 2 } } }
})
// {
// 'key1.keyA': 'valueI',
// 'key2.keyB': 'valueII',
// 'key3.a.b.c': 2
// }
var unflatten = require('flat').unflatten
unflatten({
'three.levels.deep': 42,
'three.levels': {
nested: true
}
})
// {
// three: {
// levels: {
// deep: 42,
// nested: true
// }
// }
// }
이 코드는 JSON 객체를 반복적으로 평탄화합니다.
코드에 타이밍 메커니즘을 포함시켜 1ms를 주는데 그게 가장 정확한지 모르겠어요.
var new_json = [{
"name": "fatima",
"age": 25,
"neighbour": {
"name": "taqi",
"location": "end of the street",
"property": {
"built in": 1990,
"owned": false,
"years on market": [1990, 1998, 2002, 2013],
"year short listed": [], //means never
}
},
"town": "Mountain View",
"state": "CA"
},
{
"name": "qianru",
"age": 20,
"neighbour": {
"name": "joe",
"location": "opposite to the park",
"property": {
"built in": 2011,
"owned": true,
"years on market": [1996, 2011],
"year short listed": [], //means never
}
},
"town": "Pittsburgh",
"state": "PA"
}]
function flatten(json, flattened, str_key) {
for (var key in json) {
if (json.hasOwnProperty(key)) {
if (json[key] instanceof Object && json[key] != "") {
flatten(json[key], flattened, str_key + "." + key);
} else {
flattened[str_key + "." + key] = json[key];
}
}
}
}
var flattened = {};
console.time('flatten');
flatten(new_json, flattened, "");
console.timeEnd('flatten');
for (var key in flattened){
console.log(key + ": " + flattened[key]);
}
출력:
flatten: 1ms
.0.name: fatima
.0.age: 25
.0.neighbour.name: taqi
.0.neighbour.location: end of the street
.0.neighbour.property.built in: 1990
.0.neighbour.property.owned: false
.0.neighbour.property.years on market.0: 1990
.0.neighbour.property.years on market.1: 1998
.0.neighbour.property.years on market.2: 2002
.0.neighbour.property.years on market.3: 2013
.0.neighbour.property.year short listed:
.0.town: Mountain View
.0.state: CA
.1.name: qianru
.1.age: 20
.1.neighbour.name: joe
.1.neighbour.location: opposite to the park
.1.neighbour.property.built in: 2011
.1.neighbour.property.owned: true
.1.neighbour.property.years on market.0: 1996
.1.neighbour.property.years on market.1: 2011
.1.neighbour.property.year short listed:
.1.town: Pittsburgh
.1.state: PA
제 것은 여기 있어요.Google Apps Script에서 크기가 큰 개체로 2ms 미만으로 실행됩니다.구분자로 점 대신 대시를 사용하여 질문자의 질문처럼 특별히 어레이를 처리하지는 않지만, 이것이 제가 사용하고자 했던 것입니다.
function flatten (obj) {
var newObj = {};
for (var key in obj) {
if (typeof obj[key] === 'object' && obj[key] !== null) {
var temp = flatten(obj[key])
for (var key2 in temp) {
newObj[key+"-"+key2] = temp[key2];
}
} else {
newObj[key] = obj[key];
}
}
return newObj;
}
예:
var test = {
a: 1,
b: 2,
c: {
c1: 3.1,
c2: 3.2
},
d: 4,
e: {
e1: 5.1,
e2: 5.2,
e3: {
e3a: 5.31,
e3b: 5.32
},
e4: 5.4
},
f: 6
}
Logger.log("start");
Logger.log(JSON.stringify(flatten(test),null,2));
Logger.log("done");
출력 예:
[17-02-08 13:21:05:245 CST] start
[17-02-08 13:21:05:246 CST] {
"a": 1,
"b": 2,
"c-c1": 3.1,
"c-c2": 3.2,
"d": 4,
"e-e1": 5.1,
"e-e2": 5.2,
"e-e3-e3a": 5.31,
"e-e3-e3b": 5.32,
"e-e4": 5.4,
"f": 6
}
[17-02-08 13:21:05:247 CST] done
Object.prototype.flatten = function (obj) {
let ans = {};
let anotherObj = { ...obj };
function performFlatten(anotherObj) {
Object.keys(anotherObj).forEach((key, idx) => {
if (typeof anotherObj[key] !== 'object') {
ans[key] = anotherObj[key];
console.log('ans so far : ', ans);
} else {
console.log(key, { ...anotherObj[key] });
performFlatten(anotherObj[key]);
}
})
}
performFlatten(anotherObj);
return ans;
}
let ans = flatten(obj);
console.log(ans);
선택한 답변에 +/- 10~15%의 효율성을 부가하여 마이너 코드 리팩터링 및 함수 네임스페이스 외부로 재귀 함수를 이동하였습니다.
질문 보기:네임슬레이드 기능은 모든 콜에서 재평가됩니까?네스트된 기능이 느려지는 이유에 대해 설명합니다.
function _flatten (target, obj, path) {
var i, empty;
if (obj.constructor === Object) {
empty = true;
for (i in obj) {
empty = false;
_flatten(target, obj[i], path ? path + '.' + i : i);
}
if (empty && path) {
target[path] = {};
}
}
else if (obj.constructor === Array) {
i = obj.length;
if (i > 0) {
while (i--) {
_flatten(target, obj[i], path + '[' + i + ']');
}
} else {
target[path] = [];
}
}
else {
target[path] = obj;
}
}
function flatten (data) {
var result = {};
_flatten(result, data, null);
return result;
}
벤치마크를 참조해」를 참조해 주세요.
PowerShell에 정리한 플랫의 재귀적 솔루션은 다음과 같습니다.
#---helper function for ConvertTo-JhcUtilJsonTable
#
function getNodes {
param (
[Parameter(Mandatory)]
[System.Object]
$job,
[Parameter(Mandatory)]
[System.String]
$path
)
$t = $job.GetType()
$ct = 0
$h = @{}
if ($t.Name -eq 'PSCustomObject') {
foreach ($m in Get-Member -InputObject $job -MemberType NoteProperty) {
getNodes -job $job.($m.Name) -path ($path + '.' + $m.Name)
}
}
elseif ($t.Name -eq 'Object[]') {
foreach ($o in $job) {
getNodes -job $o -path ($path + "[$ct]")
$ct++
}
}
else {
$h[$path] = $job
$h
}
}
#---flattens a JSON document object into a key value table where keys are proper JSON paths corresponding to their value
#
function ConvertTo-JhcUtilJsonTable {
param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[System.Object[]]
$jsonObj
)
begin {
$rootNode = 'root'
}
process {
foreach ($o in $jsonObj) {
$table = getNodes -job $o -path $rootNode
# $h = @{}
$a = @()
$pat = '^' + $rootNode
foreach ($i in $table) {
foreach ($k in $i.keys) {
# $h[$k -replace $pat, ''] = $i[$k]
$a += New-Object -TypeName psobject -Property @{'Key' = $($k -replace $pat, ''); 'Value' = $i[$k]}
# $h[$k -replace $pat, ''] = $i[$k]
}
}
# $h
$a
}
}
end{}
}
예:
'{"name": "John","Address": {"house": "1234", "Street": "Boogie Ave"}, "pets": [{"Type": "Dog", "Age": 4, "Toys": ["rubberBall", "rope"]},{"Type": "Cat", "Age": 7, "Toys": ["catNip"]}]}' | ConvertFrom-Json | ConvertTo-JhcUtilJsonTable
Key Value
--- -----
.Address.house 1234
.Address.Street Boogie Ave
.name John
.pets[0].Age 4
.pets[0].Toys[0] rubberBall
.pets[0].Toys[1] rope
.pets[0].Type Dog
.pets[1].Age 7
.pets[1].Toys[0] catNip
.pets[1].Type Cat
저는 json 데이터를 csv 파일로 쉽게 변환할 수 있는 방법을 원했습니다.시나리오에서는 데이터를 어딘가에서 조회하면 은행 추출물 같은 모델의 배열이 수신됩니다.다음의 어프로치는, 이러한 엔트리의 각각을 해석하기 위해서 사용됩니다.
function jsonFlatter(data, previousKey, obj) {
obj = obj || {}
previousKey = previousKey || ""
Object.keys(data).map(key => {
let newKey = `${previousKey}${previousKey ? "_" : ""}${key}`
let _value = data[key]
let isArray = Array.isArray(_value)
if (typeof _value !== "object" || isArray || _value == null) {
if (isArray) {
_value = JSON.stringify(_value)
} else if (_value == null) {
_value = "null"
}
obj[newKey] = _value
} else if (typeof _value === "object") {
if (!Object.keys(_value).length) {
obj[newKey] = "null"
} else {
return jsonFlatter(_value, newKey, obj)
}
}
})
return obj
}
이렇게 하면 오브젝트 모델의 키와 내부 키의 균일성을 기대할 수 있지만 어레이는 균일성을 신뢰할 수 없기 때문에 스트링화됩니다.또한 빈 객체는 문자열 "null"이 됩니다. 최종 결과에 해당 객체의 키가 나타나기를 원하기 때문입니다.
사용 예:
const test_data = {
a: {
aa: {
aaa: 4354,
aab: 654
},
ab: 123
},
b: 234,
c: {},
d: []
}
console.log('result', jsonFlatter(test_data))
#### output
{
"a_aa_aaa": 4354,
"a_aa_aab": 654,
"a_ab": 123,
"b": 234,
"c": "null",
"d": "[]"
}
이것을 사용해 보세요.
function getFlattenObject(data, response = {}) {
for (const key in data) {
if (typeof data[key] === 'object' && !Array.isArray(data[key])) {
getFlattenObject(data[key], response);
} else {
response[key] = data[key];
}
}
return response;
}
위의 jsFiddler를 사용하는 프로브에 따르면 현재 선택된 것보다 약간 빠른 플랫 케이스의 새로운 버전(이것이 제가 필요했던 것입니다)을 추가하고 싶습니다.게다가 저는 개인적으로 이 스니펫이 좀 더 읽기 쉽다고 생각합니다.이것은 물론 멀티 디벨로퍼 프로젝트에서 중요합니다.
function flattenObject(graph) {
let result = {},
item,
key;
function recurr(graph, path) {
if (Array.isArray(graph)) {
graph.forEach(function (itm, idx) {
key = path + '[' + idx + ']';
if (itm && typeof itm === 'object') {
recurr(itm, key);
} else {
result[key] = itm;
}
});
} else {
Reflect.ownKeys(graph).forEach(function (p) {
key = path + '.' + p;
item = graph[p];
if (item && typeof item === 'object') {
recurr(item, key);
} else {
result[key] = item;
}
});
}
}
recurr(graph, '');
return result;
}
여기 제가 작업하던 물체를 평평하게 하기 위해 작성한 코드가 있습니다.모든 중첩된 필드를 첫 번째 레이어로 가져오는 새 클래스를 만듭니다.키의 원래 위치를 기억해 두면 이 값을 unflaten으로 변경할 수 있습니다.또한 중첩된 개체 간에 키가 고유하다고 가정합니다.도움이 됐으면 좋겠다.
class JSONFlattener {
ojson = {}
flattenedjson = {}
constructor(original_json) {
this.ojson = original_json
this.flattenedjson = {}
this.flatten()
}
flatten() {
Object.keys(this.ojson).forEach(function(key){
if (this.ojson[key] == null) {
} else if (this.ojson[key].constructor == ({}).constructor) {
this.combine(new JSONFlattener(this.ojson[key]).returnJSON())
} else {
this.flattenedjson[key] = this.ojson[key]
}
}, this)
}
combine(new_json) {
//assumes new_json is a flat array
Object.keys(new_json).forEach(function(key){
if (!this.flattenedjson.hasOwnProperty(key)) {
this.flattenedjson[key] = new_json[key]
} else {
console.log(key+" is a duplicate key")
}
}, this)
}
returnJSON() {
return this.flattenedjson
}
}
console.log(new JSONFlattener(dad_dictionary).returnJSON())
예를 들어, 이 변환은
nested_json = {
"a": {
"b": {
"c": {
"d": {
"a": 0
}
}
}
},
"z": {
"b":1
},
"d": {
"c": {
"c": 2
}
}
}
안으로
{ a: 0, b: 1, c: 2 }
jpflat 패키지를 사용해 보세요.
확장, 확장, 약속 해결, 어레이 확장, 맞춤형 경로 생성 및 맞춤형 가치 직렬화가 가능합니다.
리듀서 및 시리얼라이저는 전체 경로를 부품의 배열로 받기 때문에 단일 키를 수정하거나 딜리미터를 변경하는 대신 경로에 대해 보다 복잡한 작업을 수행할 수 있습니다.
Json 경로가 기본값입니다. 따라서 "jp" 플랫입니다.
https://www.npmjs.com/package/jpflat
let flatFoo = await require('jpflat').flatten(foo)
언급URL : https://stackoverflow.com/questions/19098797/fastest-way-to-flatten-un-flatten-nested-javascript-objects
'programing' 카테고리의 다른 글
여러 테이블에서 LOCK TABLES (0) | 2022.11.21 |
---|---|
JavaScript 함수에 PHP 배열을 전달합니다. (0) | 2022.11.21 |
문자열 매개 변수를 정수 열에 암묵적으로 캐스팅하는 MariaDB 10.3 실패 (0) | 2022.11.21 |
"glob" 유형 패턴에 대해 java.util.regex와 동등한 것이 있습니까? (0) | 2022.11.21 |
"org.mariadb.jdbc"라는 이름의 JBOSS 드라이버.드라이버"가 인스톨 되어 있지 않다. (0) | 2022.11.21 |