在给出数组值时从json中提取单个属性

时间:2017-09-22 19:30:59

标签: javascript typescript lodash

当提供id数组时,我们如何从json中检索名称。

[
   {
      "id": 0,
      "name": "salesTransNo"
   },
   {
      "id": 1,
      "name": "terminalNo"
   },
   {
      "id": 2,
      "name": "salesTransDate"
   },
   {
      "id": 3,
      "name": "salesTransTime"
   },
   {
      "id": 4,
      "name": "exceptionAmount"
   },
   {
      "id": 5,
      "name": "laneNumber"
   }
]

当我给出Id值数组时,我想从json中只检索一个数组中的名称

例如:id的数组:[2,4,5]

输出应为:

[" salesTransDate"" exceptionAmount"" LaneNumber"]

我们如何使用lodash或javascript实现这一目标?

我使用_.find并使用_.map从结果中仅提取名称,但它仅用于单值,如果我传递像[2,4,5]这样的数组则不起作用。

任何帮助表示赞赏

5 个答案:

答案 0 :(得分:2)

您可以过滤对象,然后映射想要的属性。

class DogTableViewController: UITableViewController {

    var user = User()
    let profileCell = ProfileTableViewCell()
    var dogs = [Dog]()

    override func viewDidLoad() {
        super.viewDidLoad()

        let userDogRef = Database.database().reference().child("users").child(user.uid!).child("dogs")

        let userProfileImageView = UIImageView()
        userProfileImageView.translatesAutoresizingMaskIntoConstraints = false
        userProfileImageView.widthAnchor.constraint(equalToConstant: 40).isActive = true
        userProfileImageView.heightAnchor.constraint(equalToConstant: 40).isActive = true
        userProfileImageView.layer.cornerRadius = 20
        userProfileImageView.clipsToBounds = true
        userProfileImageView.contentMode = .scaleAspectFill
        userProfileImageView.image = UIImage(named: "AppIcon")

        navigationItem.titleView = userProfileImageView

        //MARK: Download dogs from firebase
        userDogRef.observe(.childAdded, with: { (snapshot) in
            if snapshot.value == nil {
                print("no new dog found")
            } else {
                print("new dog found")

                let snapshotValue = snapshot.value as! Dictionary<String, String>
                let dogID = snapshotValue["dogID"]!

                let dogRef = Database.database().reference().child("dogs").child(dogID)
                dogRef.observeSingleEvent(of: .value, with: { (snap) in
                    print("Found dog data!")
                    let value  = snap.value as? NSDictionary
                    let newDog = Dog()

                    newDog.name = value?["name"] as? String ?? ""
                    newDog.breed = value?["breed"] as? String ?? ""
                    newDog.creator = value?["creator"] as? String ?? ""
                    newDog.score = Int(value?["score"] as? String ?? "")
                    newDog.imageURL = value?["imageURL"] as? String ?? ""
                    newDog.dogID = snapshot.key

                    URLSession.shared.dataTask(with: URL(string: newDog.imageURL!)!, completionHandler: { (data, response, error) in
                        if error != nil {
                            print(error!)
                            return
                        }
                        newDog.picture = UIImage(data: data!)!
                        self.dogs.append(newDog)
                        DispatchQueue.main.async {
                            self.tableView.reloadData()
                        }
                    }).resume()
                })
            }
        })

        tableView.estimatedRowHeight = 454
    }

    // MARK: - Table view data source

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dogs.count + 1
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.row == 0 {
            let profileCell = tableView.dequeueReusableCell(withIdentifier: "profileCell", for: indexPath) as! ProfileTableViewCell
            profileCell.nameLabel.text = user.name
            profileCell.totalReputationLabel.text = String(describing: user.reputation!)
            profileCell.usernameLabel.text = user.username
            return profileCell
        } else {
            let dogCell = tableView.dequeueReusableCell(withIdentifier: "dogCell", for: indexPath) as! DogTableViewCell
            dogCell.dogBreedLabel.text = dogs[indexPath.row].breed
            dogCell.dogNameLabel.text = dogs[indexPath.row].name
            dogCell.dogScoreLabel.text = String(describing: dogs[indexPath.row].score)
            dogCell.dogImageView.image = dogs[indexPath.row].picture
            dogCell.dogCreatorButton.titleLabel?.text = dogs[indexPath.row].creator
            dogCell.dogVotesLabel.text = "0"
            return dogCell
        }

    }
}

答案 1 :(得分:0)

&#13;
&#13;
var items = [{
    "id": 0,
    "name": "salesTransNo"
  },
  {
    "id": 1,
    "name": "terminalNo"
  },
  {
    "id": 2,
    "name": "salesTransDate"
  },
  {
    "id": 3,
    "name": "salesTransTime"
  },
  {
    "id": 4,
    "name": "exceptionAmount"
  },
  {
    "id": 5,
    "name": "laneNumber"
  }
]

var iname = items.filter(items => [2, 4, 5].includes(items.id));

for (var names of iname)
{console.log(names.name);}
&#13;
&#13;
&#13;

答案 2 :(得分:0)

您可以使用_.keyBy()_.at()_.map()使用lodash链做到这一点:

&#13;
&#13;
var data = [{ id: 0, name: "salesTransNo" }, { id: 1, name: "terminalNo" }, { id: 2, name: "salesTransDate" }, { id: 3, name: "salesTransTime" }, { id: 4, name: "exceptionAmount" }, { id: 5, name: "laneNumber" }];
var ids = [2, 4, 5];

var result = _(data)
  .keyBy('id') // convert to a dictionary by id
  .at(ids) // get the items which id match the id array
  .map('name') // pluck the name
  .value();
  
console.log(result);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

您可以使用lodash#intersectionWith,其中参数顺序必须首先是集合,第二个是ids,最后是比较器。

var result = _.intersectionWith(data, ids, (a, b) => a.id == b);

var data = [{
    id: 0,
    name: "salesTransNo"
  }, {
    id: 1,
    name: "terminalNo"
  }, {
    id: 2,
    name: "salesTransDate"
  }, {
    id: 3,
    name: "salesTransTime"
  }, {
    id: 4,
    name: "exceptionAmount"
  }, {
    id: 5,
    name: "laneNumber"
  }],
  ids = [2, 4, 5];
  
var result = _.intersectionWith(data, ids, (a, b) => a.id == b);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

答案 4 :(得分:0)

Vanilla JS:

var arr = [
   { "id": 0, "name": "salesTransNo"  },
   { "id": 1, "name": "terminalNo" },
   { "id": 2, "name": "salesTransDate" },
   { "id": 3, "name": "salesTransTime" },
   { "id": 4, "name": "exceptionAmount" },
   { "id": 5, "name": "laneNumber" }
];

var indexes = arr.map ( function ( d ) { return d.id; });

var id = 4; // Requested arr.id item
var select_name = arr[indexes.indexOf(id)].name;

如果您希望返回多个结果,可以构建如下函数:

function getNamesFromArr ( list_of_ids ) {
   var result = [];
   for ( var i = 0; i < list_of_ids.length; i++ ) {
      var indexes = arr.map ( function ( d ) { return d.id; });
      var select_name = arr[indexes.indexOf(list_of_ids[i])].name;
      result.push ( select_name );
   }
   return result;
}

getNamesFromArr ([ 2, 4, 5 ]); // Returns ["salesTransDate", "exceptionAmount", "laneNumber"]

注意:为简单起见,我遗漏了错误处理。考虑捕获indexOf()值为-1。