2017-08-27 30 views
1

私はいくつかの単一のアイテムや、いくつかの配列を含む配列があります。機能 - javascriptの

var groceries = ["toothpaste", ["plums", "peaches", "pineapples"], ["carrots", "corn", "green beans"], "orange juice", ["chocolate", "ice cream"], "paper towels", "fish"]; 

を私はこれらの項目または配列の一部を削除する機能を書きたいです呼び出されると。単一項目について

、私はこの関数を書いた:

removeItems(groceries, ["fish", "orange juice"]); 

そして、私はそれがしたいので、これは正確に動作します:

function removeItems(arr, item) { 
    for (var i = 0; i < item.length; i++) { 
    var index = arr.indexOf(item[i]); 
    if (index > -1) { 
     arr.splice(index, 1); 
    } 
    } 
}; 

それでは、私は呼び出すことができます。しかし、関数を大型配列内から配列(例:["チョコレート"、 "アイスクリーム"など)も削除できるようにする方法を理解できません。それについてどうすればいいのですか?

+0

「チョコレート」を削除したい場合は、チョコレートまたはアレイ[「チョコレート」、「アイスクリーム」]を削除するだけです – marvel308

+0

私は決してアレイ内の一部のアレイを削除したくありません。単一項目または配列全体のみを削除してください。それは理にかなっていますか?だからあなたの例では、["チョコレート"、 "アイスクリーム"]。 – sprucegoose

答えて

4

Array#reduceを使用してキーの辞書を作成します。項目が配列の場合は、すべての値を結合してキーを作成します。その後、同じキーを生成し、辞書と照合してすべての項目をフィルタリングします。

注 - アレイ#フィルタは新しいアレイを作成し、元のアレイは変更しません。被写体からの要素を削除するような問題で

var groceries = ["toothpaste", ["plums", "peaches", "pineapples"], ["carrots", "corn", "green beans"], "orange juice", ["chocolate", "ice cream"], "paper towels", "fish"]; 
 

 
function removeItems(arr, toRemove) { 
 
    function createKey(item) { 
 
    return Array.isArray(item) ? item.join('-') : item; 
 
    } 
 

 
    var removeDict = toRemove.reduce(function(d, item) { 
 
    var key = createKey(item); 
 
    
 
    d[key] = true; 
 
    
 
    return d; 
 
    }, {}); 
 

 
    return arr.filter(function(item) { 
 
    var key = createKey(item); 
 
    
 
    return !removeDict[key]; 
 
    }); 
 
} 
 

 
var result = removeItems(groceries, ["fish", "orange juice", ["chocolate", "ice cream"]]); 
 

 
console.log(result);

+0

これは完璧です。説明してくれてありがとう、本当に役立つ。 – sprucegoose

+0

@ sprucegoose - welcome :) –

+0

'createKey'の代わりに' JSON.stringify'を使ってみませんか? [私の答え](https://stackoverflow.com/a/45902961/783743)を参照してください。 –

0

、私は、彼らはあなたがアイテムを削除を開始しても、最初の項目数に応じて反復されますので、離れた機能的配列メソッドを使用してから滞在する傾向があります。ですから、私の解決策はむしろ不可欠です。

function remover(itemToDelete, items){ 
 
    var i  = 0, 
 
     check = false; 
 
    
 
    for (var item of items){ 
 
    check = Array.isArray(item) ? item.includes(itemToDelete) 
 
           : item === itemToDelete; 
 
    check ? items.splice(i,1) 
 
      : i++; 
 
    } 
 
    return items; 
 
} 
 

 
var groceries = ["toothpaste", ["plums", "peaches", "pineapples"], ["carrots", "corn", "green beans"], "orange juice", ["chocolate", "ice cream"], "paper towels", "fish"]; 
 

 
console.log(remover("chocolate", groceries)); 
 
console.log(remover("fish", groceries));

0

これは私がやるだろうと何である:

const groceries = [ 
 
    "toothpaste", 
 
    ["plums", "peaches", "pineapples"], 
 
    ["carrots", "corn", "green beans"], 
 
    "orange juice", 
 
    ["chocolate", "ice cream"], 
 
    "paper towels", 
 
    "fish" 
 
]; 
 

 
const equals = (x, y) => JSON.stringify(x) === JSON.stringify(y); 
 

 
const removeItems = (xs, ys) => xs.filter(x => !ys.some(y => equals(x, y))); 
 

 
const result = removeItems(groceries, [ 
 
    "fish", 
 
    "orange juice", 
 
    ["chocolate", "ice cream"] 
 
]); 
 

 
console.log(result);

まず、我々は、2つの値が等しくなるようにするためにそれが何を意味するのかを定義します。次に、この値の等価性を使用してremoveItemsを定義します。私たちは、すべてのどれもがyと等しくないようにしておきます。