2016-07-02 3 views
1

Я не могу найти аналогичный вопрос, и я немного застрял. У меня есть следующие JSON массив:Возвращает уникальные значения массива из массива внутри массива объектов

[ 
    { 
     "Name": "element1", 
     "Attributes": ["1", "2"] 
    }, 

    { 
     "Name": "element2", 
     "Attributes": ["1","3" ] 
    }, 
    { 
     "Name": "element3", 
     "Attributes": [] 
    } 
] 

Я пытаюсь создать массив всех уникальных элементов в «Атрибуты» собственность, но у меня возникают проблемы с зацикливание каждый объект, а затем через циклическую чтобы вернуть уникальные значения. Я пытаюсь сделать это с помощью фильтра() или map().

EDIT: Я хочу массив уникальных элементов, поэтому: [1,2,3].

+0

пожалуйста, добавьте желаемый результат и код, который вы пробовали. –

+0

I'vr добавил мой желаемый результат, но я застрял в том, как делать фильтр() внутри map(), и возвращать вывод внутреннего фильтра() для резервного копирования содержащейся карты() – DorianHuxley

+0

Возможный дубликат [Доступ/процесс (вложенные) объекты, массивы или JSON] (http://stackoverflow.com/questions/11922383/access-process-nested-objects-arrays-or-json) – Teemu

ответ

1

Вы можете сделать это с парой методов массива. Например:

var result = [ 
 
    { 
 
     "Name": "element1", 
 
     "Attributes": ["1", "2"] 
 
    }, 
 

 
    { 
 
     "Name": "element2", 
 
     "Attributes": ["1","3" ] 
 
    }, 
 
    { 
 
     "Name": "element3", 
 
     "Attributes": [] 
 
    } 
 
] 
 

 
// map to [ ["1", "2"], ["1", "3"], [] ] 
 
.map(item => item.Attributes) 
 

 
// flatten to [ "1", "2", "1", "3" ] 
 
.reduce((prev, curr) => prev.concat(curr), []) 
 

 
// filter unique [ "1", "2", "3" ] 
 
.filter((item, i, arr) => arr.indexOf(item) === i) 
 

 
console.log(result)

+0

Нет необходимости использовать 'apply',' return prev.concat (curr) 'достаточно –

0
var uniqueArr = []; 

var arr = [ 
    { 
     "Name": "element1", 
     "Attributes": ["1", "2"] 
    }, 

    { 
     "Name": "element2", 
     "Attributes": ["1","3" ] 
    }, 
    { 
     "Name": "element3", 
     "Attributes": [] 
    } 
]; 

arr.forEach(function(obj) { 
    var attr = obj.Attributes; 
    attr.forEach(function(val){ 
     if (uniqueArray.indexOf(val) < 0) { 
      uniqueArray.push(val) 
     } 
    }); 
}) 
1

Вы можете использовать Array#reduce и Array#filter методы

var data = [{ 
 
    "Name": "element1", 
 
    "Attributes": ["1", "2"] 
 
    }, 
 

 
    { 
 
    "Name": "element2", 
 
    "Attributes": ["1", "3"] 
 
    }, { 
 
    "Name": "element3", 
 
    "Attributes": [] 
 
    } 
 
] 
 

 
console.log(
 
    // iterate over array elements 
 
    data.reduce(function(arr, ele) { 
 
    // push the unique values to array 
 
    [].push.apply(arr, 
 
     // filter out unique value 
 
     ele.Attributes.filter(function(v) { 
 
     // check element present in array 
 
     return arr.indexOf(v) == -1; 
 
     }) 
 
    ); 
 
    // return the unique array 
 
    return arr; 
 
    // set initial argument as an empty array 
 
    }, []) 
 
);


С ES6 arrow function

var data = [{ 
 
    "Name": "element1", 
 
    "Attributes": ["1", "2"] 
 
    }, 
 

 
    { 
 
    "Name": "element2", 
 
    "Attributes": ["1", "3"] 
 
    }, { 
 
    "Name": "element3", 
 
    "Attributes": [] 
 
    } 
 
] 
 

 
console.log(
 
    data.reduce((arr, ele) => ([].push.apply(arr, ele.Attributes.filter((v) => arr.indexOf(v) == -1)), arr), []) 
 
);

0

Если lodash является вариант, вы можете легко получить то, что вы хотите:

> _.chain(foo).map('Attributes').flatten().uniq().value() 
["1", "2", "3"] 
0

У вас есть ответы на выбор. Просто для удовольствия: это один использует ES6

"use strict"; 
 
let uniqueAttr = []; 
 
const obj = [ 
 
    { 
 
     "Name": "element1", 
 
     "Attributes": ["1", "2"] 
 
    }, 
 

 
    { 
 
     "Name": "element2", 
 
     "Attributes": ["1","3" ] 
 
    }, 
 
    { 
 
     "Name": "element3", 
 
     "Attributes": [] 
 
    } 
 
]; 
 

 
obj.forEach(element => 
 
    element.Attributes.forEach( 
 
    attr => uniqueAttr.indexOf(attr) < 0 && uniqueAttr.push(attr) 
 
) 
 
); 
 

 
document.querySelector("#result").textContent = uniqueAttr;
<pre id="result"></pre>

0

Попробуйте это, это поможет решить эту проблему.

var data = [{ 
 
    "Name": "element1", 
 
    "Attributes": ["1", "2"] 
 
    }, { 
 
    "Name": "element2", 
 
    "Attributes": ["1", "3"] 
 
    }, { 
 
    "Name": "element3", 
 
    "Attributes": [] 
 
    }]; 
 
    var Attributes = []; 
 
    $.each(data, function(i, e) { 
 
    $.each(e.Attributes, function(i, e) { 
 
     Attributes.push(parseInt(e)); 
 
    }); 
 
    }); 
 
    Attributes = $.unique(Attributes); 
 
    alert(Attributes);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

Смежные вопросы