解析

2016-12-18 2 views
0

はのは、私はフォームを持っている、と私は入力フォームで宣言されているものを確認したいので、私はこのような何かを言ってみましょうとても良い。解析

しかし、入力が['name.first', 'name.last']の場合はどうなりますか?

{name.first: '...', name.last: '...'}. 

をし、このようにしない:そして、それは次のようにオブジェクトにデータを格納するオブジェクトとしてそれを解析するために、私はJavaScriptを伝えることができますどのように

{ 
    name: { 
     first: '...', 
     last: '...' 
    } 
} 

(私の望ましい結果であるが)キー文字列の代わりにパス?

+0

あなたが実際に 'map'を行っていないとして、あなたの最初の例では、より良い' forEach'あるいは 'reduce'に書き込まれます。また、結果をフィルタリングするために名前の固定配列を使用する理由について私は興味がありますか?おそらくあなたは何をやっているのかもう少し説明できますか? – Xotic750

+0

あなたは正しかった、 'forEach'の代わりに' map'を使うことは全くスマートではありませんでした。それは間違いでした。 –

答えて

1

カスタム割り当て機能を使用します。

オブジェクトは任意の文字列をキーとして使用できるため、 "a.b"が有効です。

function assign(obj, key, value) { 
    let keys = key.split("."); 
    let last = keys.pop(); 
    keys.forEach(key => { 
     if(!obj[key]) 
      obj[key] = {}; 
     obj = obj[key]; 
    }); 

    obj[last] = value; 
} 

let obj = {}; 
assign(obj, "name.first", "hey"); 
assign(obj, "name.last", "bye"); 

console.log(obj); 

ボーナスrecomendation:あなたはすべてのフォームに同じ形式を使用する場合は、グローバルフォームハンドラとして使用することができます。ここ

はアサイン機能の一例です。

function formHandler(form) { 
    let obj = {}; 
    form.querySelectorAll("input, select").forEach(elem => assign(obj, elem.name, elem.value)); 
    return obj; 
} 
0

これは何ですか?

var obj = { 
     'prop': 'value', 
     'nested.prop1': 'value1', 
     'nested.prop2': 'value2', 
     'renested.prop1': 'value1', 
     'renested.prop2': 'value2',  
     'nested.prop3': 'value3', 
    } 

    function deconcatProp(obj){ 

     var idx; 
     var key; 

     for(var prop in obj){ 
      if((idx = prop.indexOf('.')) > 0){ 
       key = prop.substring(0, idx); 
       if(!obj[key]) { 
        obj[key] = { 
        }; 
       } 
       obj[key][prop.substring(idx + 1, prop.length)] = obj[prop]; 
       delete obj[prop]; 
      } 
     } 

    } 

deconcatProp(obj); 
0

パスを作成するための他の回答(スプリット、テストおよび作成)と同じ原理を使用しますが、(私のコメントで述べたように)あなたのフィルタリング例の代替を示しています。

const wanted = ['name.first', 'name.second', 'name.last']; 
 
const result = Array.from(document.querySelectorAll('input')) 
 
    .filter(input => wanted.includes(input.name)) 
 
    .reduce((a, input) => { 
 
    const paths = input.name.split('.'); 
 
    const key = paths.pop(); 
 
    let current = a; 
 
    paths.forEach(path => current = current[path] ? 
 
     current[path] : 
 
     current[path] = Object.create(null)); 
 
    current[key] = input.value; 
 
    return a; 
 
    }, Object.create(null)); 
 

 
console.log(result);
<input name="name.first" value="Eliya" /> 
 
<input name="name.middle" value="Wibble" /> 
 
<input name="name.last" value="Cohen" />